]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Splitting implementation of UMesh to isolate intersection and
authorabn <adrien.bruneton@cea.fr>
Fri, 17 Feb 2017 10:36:42 +0000 (11:36 +0100)
committerabn <adrien.bruneton@cea.fr>
Fri, 17 Feb 2017 10:42:24 +0000 (11:42 +0100)
internal stuff.

MEDCouplingUMesh.cxx down to 8k LOC :-)

src/MEDCoupling/CMakeLists.txt
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling/MEDCouplingUMesh_internal.cxx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingUMesh_internal.hxx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingUMesh_intersection.cxx [new file with mode: 0644]

index 4c66e6dd6aaca891bb553de4838d88838d7e69db..34ae94365739c5d7fd0f1fc605174c723d171c06 100644 (file)
@@ -37,6 +37,8 @@ SET(medcoupling_SOURCES
   MEDCouplingFieldDouble.cxx
   MEDCouplingFieldInt.cxx
   MEDCouplingUMesh.cxx
+  MEDCouplingUMesh_internal.cxx
+  MEDCouplingUMesh_intersection.cxx
   MEDCoupling1GTUMesh.cxx
   MEDCouplingMemArray.cxx
   MEDCouplingMemArrayChar.cxx
index cbff1a12d8e367ac92ef1a366caef97877316b10..907b00d6f09955cc249b0bc5dba8995480abc691 100644 (file)
@@ -41,6 +41,7 @@
 #include "InterpKernelGeo2DEdgeLin.hxx"
 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
 #include "InterpKernelGeo2DQuadraticPolygon.hxx"
+#include "MEDCouplingUMesh_internal.hxx"
 
 #include <sstream>
 #include <fstream>
@@ -621,83 +622,6 @@ void MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataA
     }
 }
 
-/// @cond INTERNAL
-
-int MEDCouplingFastNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2)
-{
-  return id;
-}
-
-int MEDCouplingOrientationSensitiveNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2)
-{
-  if(!compute)
-    return id+1;
-  else
-    {
-      if(cm.getOrientationStatus(nb,conn1,conn2))
-        return id+1;
-      else
-        return -(id+1);
-    }
-}
-
-class MinusOneSonsGenerator
-{
-public:
-  MinusOneSonsGenerator(const INTERP_KERNEL::CellModel& cm):_cm(cm) { }
-  unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfSons2(conn,lgth); }
-  unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonCellNodalConnectivity2(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); }
-  static const int DELTA=1;
-private:
-  const INTERP_KERNEL::CellModel& _cm;
-};
-
-class MinusOneSonsGeneratorBiQuadratic
-{
-public:
-  MinusOneSonsGeneratorBiQuadratic(const INTERP_KERNEL::CellModel& cm):_cm(cm) { }
-  unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfSons2(conn,lgth); }
-  unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonCellNodalConnectivity4(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); }
-  static const int DELTA=1;
-private:
-  const INTERP_KERNEL::CellModel& _cm;
-};
-
-class MinusTwoSonsGenerator
-{
-public:
-  MinusTwoSonsGenerator(const INTERP_KERNEL::CellModel& cm):_cm(cm) { }
-  unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfEdgesIn3D(conn,lgth); }
-  unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonEdgesNodalConnectivity3D(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); }
-  static const int DELTA=2;
-private:
-  const INTERP_KERNEL::CellModel& _cm;
-};
-
-class MicroEdgesGenerator2D
-{
-public:
-  MicroEdgesGenerator2D(const INTERP_KERNEL::CellModel& cm):_cm(cm) { }
-  unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfMicroEdges(); }
-  unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillMicroEdgeNodalConnectivity(sonId,nodalConn,sonNodalConn,typeOfSon); }
-  static const int DELTA=1;
-private:
-  const INTERP_KERNEL::CellModel& _cm;
-};
-
-class MicroEdgesGenerator3D
-{
-public:
-  MicroEdgesGenerator3D(const INTERP_KERNEL::CellModel& cm):_cm(cm) { }
-  unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfMicroEdges(); }
-  unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillMicroEdgeNodalConnectivity(sonId,nodalConn,sonNodalConn,typeOfSon); }
-  static const int DELTA=2;
-private:
-  const INTERP_KERNEL::CellModel& _cm;
-};
-
-/// @endcond
-
 /*!
  * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a
  * this->getMeshDimension(), that bound cells of \a this mesh. In addition arrays
@@ -998,134 +922,6 @@ void MEDCouplingUMesh::computeNeighborsOfNodes(DataArrayInt *&neighbors, DataArr
   neighborsIdx=descIndx.retn();
 }
 
-/// @cond INTERNAL
-
-/*!
- * \b WARNING this method do the assumption that connectivity lies on the coordinates set.
- * For speed reasons no check of this will be done.
- */
-template<class SonsGenerator>
-MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const
-{
-  if(!desc || !descIndx || !revDesc || !revDescIndx)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildDescendingConnectivityGen : present of a null pointer in input !");
-  checkConnectivityFullyDefined();
-  int nbOfCells=getNumberOfCells();
-  int nbOfNodes=getNumberOfNodes();
-  MCAuto<DataArrayInt> revNodalIndx=DataArrayInt::New(); revNodalIndx->alloc(nbOfNodes+1,1); revNodalIndx->fillWithZero();
-  int *revNodalIndxPtr=revNodalIndx->getPointer();
-  const int *conn=_nodal_connec->getConstPointer();
-  const int *connIndex=_nodal_connec_index->getConstPointer();
-  std::string name="Mesh constituent of "; name+=getName();
-  MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(name,getMeshDimension()-SonsGenerator::DELTA);
-  ret->setCoords(getCoords());
-  ret->allocateCells(2*nbOfCells);
-  descIndx->alloc(nbOfCells+1,1);
-  MCAuto<DataArrayInt> revDesc2(DataArrayInt::New()); revDesc2->reserve(2*nbOfCells);
-  int *descIndxPtr=descIndx->getPointer(); *descIndxPtr++=0;
-  for(int eltId=0;eltId<nbOfCells;eltId++,descIndxPtr++)
-    {
-      int pos=connIndex[eltId];
-      int posP1=connIndex[eltId+1];
-      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[pos]);
-      SonsGenerator sg(cm);
-      unsigned nbOfSons=sg.getNumberOfSons2(conn+pos+1,posP1-pos-1);
-      INTERP_KERNEL::AutoPtr<int> tmp=new int[posP1-pos];
-      for(unsigned i=0;i<nbOfSons;i++)
-        {
-          INTERP_KERNEL::NormalizedCellType cmsId;
-          unsigned nbOfNodesSon=sg.fillSonCellNodalConnectivity2(i,conn+pos+1,posP1-pos-1,tmp,cmsId);
-          for(unsigned k=0;k<nbOfNodesSon;k++)
-            if(tmp[k]>=0)
-              revNodalIndxPtr[tmp[k]+1]++;
-          ret->insertNextCell(cmsId,nbOfNodesSon,tmp);
-          revDesc2->pushBackSilent(eltId);
-        }
-      descIndxPtr[0]=descIndxPtr[-1]+(int)nbOfSons;
-    }
-  int nbOfCellsM1=ret->getNumberOfCells();
-  std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
-  MCAuto<DataArrayInt> revNodal=DataArrayInt::New(); revNodal->alloc(revNodalIndx->back(),1);
-  std::fill(revNodal->getPointer(),revNodal->getPointer()+revNodalIndx->back(),-1);
-  int *revNodalPtr=revNodal->getPointer();
-  const int *connM1=ret->getNodalConnectivity()->getConstPointer();
-  const int *connIndexM1=ret->getNodalConnectivityIndex()->getConstPointer();
-  for(int eltId=0;eltId<nbOfCellsM1;eltId++)
-    {
-      const int *strtNdlConnOfCurCell=connM1+connIndexM1[eltId]+1;
-      const int *endNdlConnOfCurCell=connM1+connIndexM1[eltId+1];
-      for(const int *iter=strtNdlConnOfCurCell;iter!=endNdlConnOfCurCell;iter++)
-        if(*iter>=0)//for polyhedrons
-          *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
-    }
-  //
-  DataArrayInt *commonCells=0,*commonCellsI=0;
-  FindCommonCellsAlg(3,0,ret->getNodalConnectivity(),ret->getNodalConnectivityIndex(),revNodal,revNodalIndx,commonCells,commonCellsI);
-  MCAuto<DataArrayInt> commonCellsTmp(commonCells),commonCellsITmp(commonCellsI);
-  const int *commonCellsPtr(commonCells->getConstPointer()),*commonCellsIPtr(commonCellsI->getConstPointer());
-  int newNbOfCellsM1=-1;
-  MCAuto<DataArrayInt> o2nM1=DataArrayInt::ConvertIndexArrayToO2N(nbOfCellsM1,commonCells->begin(),
-                                                                                                            commonCellsI->begin(),commonCellsI->end(),newNbOfCellsM1);
-  std::vector<bool> isImpacted(nbOfCellsM1,false);
-  for(const int *work=commonCellsI->begin();work!=commonCellsI->end()-1;work++)
-    for(int work2=work[0];work2!=work[1];work2++)
-      isImpacted[commonCellsPtr[work2]]=true;
-  const int *o2nM1Ptr=o2nM1->getConstPointer();
-  MCAuto<DataArrayInt> n2oM1=o2nM1->invertArrayO2N2N2OBis(newNbOfCellsM1);
-  const int *n2oM1Ptr=n2oM1->getConstPointer();
-  MCAuto<MEDCouplingUMesh> ret2=static_cast<MEDCouplingUMesh *>(ret->buildPartOfMySelf(n2oM1->begin(),n2oM1->end(),true));
-  ret2->copyTinyInfoFrom(this);
-  desc->alloc(descIndx->back(),1);
-  int *descPtr=desc->getPointer();
-  const INTERP_KERNEL::CellModel& cmsDft=INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_POINT1);
-  for(int i=0;i<nbOfCellsM1;i++,descPtr++)
-    {
-      if(!isImpacted[i])
-        *descPtr=nbrer(o2nM1Ptr[i],0,cmsDft,false,0,0);
-      else
-        {
-          if(i!=n2oM1Ptr[o2nM1Ptr[i]])
-            {
-              const INTERP_KERNEL::CellModel& cms=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)connM1[connIndexM1[i]]);
-              *descPtr=nbrer(o2nM1Ptr[i],connIndexM1[i+1]-connIndexM1[i]-1,cms,true,connM1+connIndexM1[n2oM1Ptr[o2nM1Ptr[i]]]+1,connM1+connIndexM1[i]+1);
-            }
-          else
-            *descPtr=nbrer(o2nM1Ptr[i],0,cmsDft,false,0,0);
-        }
-    }
-  revDesc->reserve(newNbOfCellsM1);
-  revDescIndx->alloc(newNbOfCellsM1+1,1);
-  int *revDescIndxPtr=revDescIndx->getPointer(); *revDescIndxPtr++=0;
-  const int *revDesc2Ptr=revDesc2->getConstPointer();
-  for(int i=0;i<newNbOfCellsM1;i++,revDescIndxPtr++)
-    {
-      int oldCellIdM1=n2oM1Ptr[i];
-      if(!isImpacted[oldCellIdM1])
-        {
-          revDesc->pushBackSilent(revDesc2Ptr[oldCellIdM1]);
-          revDescIndxPtr[0]=revDescIndxPtr[-1]+1;
-        }
-      else
-        {
-          for(int j=commonCellsIPtr[0];j<commonCellsIPtr[1];j++)
-            revDesc->pushBackSilent(revDesc2Ptr[commonCellsPtr[j]]);
-          revDescIndxPtr[0]=revDescIndxPtr[-1]+commonCellsIPtr[1]-commonCellsIPtr[0];
-          commonCellsIPtr++;
-        }
-    }
-  //
-  return ret2.retn();
-}
-
-struct MEDCouplingAccVisit
-{
-  MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
-  int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
-  int _new_nb_of_nodes;
-};
-
-/// @endcond
-
 /*!
  * Converts specified cells to either polygons (if \a this is a 2D mesh) or
  * polyhedrons (if \a this is a 3D mesh). The cells to convert are specified by an
@@ -1501,6 +1297,17 @@ void MEDCouplingUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
         }
 }
 
+/// @cond INTERNAL
+
+struct MEDCouplingAccVisit
+{
+  MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
+  int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
+  int _new_nb_of_nodes;
+};
+
+/// @endcond
+
 /*!
  * Finds nodes not used in any cell and returns an array giving a new id to every node
  * by excluding the unused nodes, for which the array holds -1. The result array is
@@ -1809,39 +1616,6 @@ int MEDCouplingUMesh::AreCellsEqualPolicy7(const int *conn, const int *connI, in
   return 0;
 }
 
-/*!
- * This method find in candidate pool defined by 'candidates' the cells equal following the polycy 'compType'.
- * If any true is returned and the results will be put at the end of 'result' output parameter. If not false is returned
- * and result remains unchanged.
- * The semantic of 'compType' is specified in MEDCouplingPointSet::zipConnectivityTraducer method.
- * If in 'candidates' pool -1 value is considered as an empty value.
- * WARNING this method returns only ONE set of result !
- */
-bool MEDCouplingUMesh::AreCellsEqualInPool(const std::vector<int>& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result)
-{
-  if(candidates.size()<1)
-    return false;
-  bool ret=false;
-  std::vector<int>::const_iterator iter=candidates.begin();
-  int start=(*iter++);
-  for(;iter!=candidates.end();iter++)
-    {
-      int status=AreCellsEqual(conn,connI,start,*iter,compType);
-      if(status!=0)
-        {
-          if(!ret)
-            {
-              result->pushBackSilent(start);
-              ret=true;
-            }
-          if(status==1)
-            result->pushBackSilent(*iter);
-          else
-            result->pushBackSilent(status==2?(*iter+1):-(*iter+1));
-        }
-    }
-  return ret;
-}
 
 /*!
  * This method find cells that are equal (regarding \a compType) in \a this. The comparison is specified
@@ -2230,45 +2004,6 @@ void MEDCouplingUMesh::setPartOfMySelfSlice(int start, int end, int step, const
     }
 }                      
 
-/*!
- * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ).
- * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
- * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
- * If \a fullyIn is true only cells whose ids are \b fully contained in [ \a begin,\a end ) tab will be kept.
- *
- * \param [in] begin input start of array of node ids.
- * \param [in] end input end of array of node ids.
- * \param [in] fullyIn input that specifies if all node ids must be in [ \a begin,\a end ) array to consider cell to be in.
- * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
- */
-void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
-{
-  MCAuto<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
-  checkConnectivityFullyDefined();
-  int tmp=-1;
-  int sz=getNodalConnectivity()->getMaxValue(tmp); sz=std::max(sz,0)+1;
-  std::vector<bool> fastFinder(sz,false);
-  for(const int *work=begin;work!=end;work++)
-    if(*work>=0 && *work<sz)
-      fastFinder[*work]=true;
-  int nbOfCells=getNumberOfCells();
-  const int *conn=getNodalConnectivity()->getConstPointer();
-  const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
-  for(int i=0;i<nbOfCells;i++)
-    {
-      int ref=0,nbOfHit=0;
-      for(const int *work2=conn+connIndex[i]+1;work2!=conn+connIndex[i+1];work2++)
-        if(*work2>=0)
-          {
-            ref++;
-            if(fastFinder[*work2])
-              nbOfHit++;
-          }
-      if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
-        cellIdsKept->pushBackSilent(i);
-    }
-  cellIdsKeptArr=cellIdsKept.retn();
-}
 
 /*!
  * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a
@@ -3186,25 +2921,6 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSetInstanceFromThis(int spaceDim) const
   return ret.retn();
 }
 
-void MEDCouplingUMesh::reprConnectivityOfThisLL(std::ostringstream& stream) const
-{
-  if(_nodal_connec!=0 && _nodal_connec_index!=0)
-    {
-      int nbOfCells=getNumberOfCells();
-      const int *c=_nodal_connec->getConstPointer();
-      const int *ci=_nodal_connec_index->getConstPointer();
-      for(int i=0;i<nbOfCells;i++)
-        {
-          const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[i]]);
-          stream << "Cell #" << i << " " << cm.getRepr() << " : ";
-          std::copy(c+ci[i]+1,c+ci[i+1],std::ostream_iterator<int>(stream," "));
-          stream << "\n";
-        }
-    }
-  else
-    stream << "Connectivity not defined !\n";
-}
-
 int MEDCouplingUMesh::getNumberOfNodesInCell(int cellId) const
 {
   const int *ptI=_nodal_connec_index->getConstPointer();
@@ -3288,23 +3004,6 @@ void MEDCouplingUMesh::computeTypes()
   ComputeAllTypesInternal(_types,_nodal_connec,_nodal_connec_index);
 }
 
-/*!
- * This method checks that all arrays are set. If yes nothing done if no an exception is thrown.
- */
-void MEDCouplingUMesh::checkFullyDefined() const
-{
-  if(!_nodal_connec_index || !_nodal_connec || !_coords)
-    throw INTERP_KERNEL::Exception("Reverse nodal connectivity computation requires full connectivity and coordinates set in unstructured mesh.");
-}
-
-/*!
- * This method checks that all connectivity arrays are set. If yes nothing done if no an exception is thrown.
- */
-void MEDCouplingUMesh::checkConnectivityFullyDefined() const
-{
-  if(!_nodal_connec_index || !_nodal_connec)
-    throw INTERP_KERNEL::Exception("Reverse nodal connectivity computation requires full connectivity set in unstructured mesh.");
-}
 
 /*!
  * Returns a number of cells constituting \a this mesh. 
@@ -3424,96 +3123,7 @@ void MEDCouplingUMesh::unserialization(const std::vector<double>& tinyInfoD, con
     }
 }
 
-/*!
- * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelfSlice.
- * CellIds are given using range specified by a start an end and step.
- */
-MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoordsSlice(int start, int end, int step) const
-{
-  checkFullyDefined();
-  int ncell=getNumberOfCells();
-  MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
-  ret->_mesh_dim=_mesh_dim;
-  ret->setCoords(_coords);
-  int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelfKeepCoordsSlice : ");
-  MCAuto<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(newNbOfCells+1,1);
-  int *newConnIPtr=newConnI->getPointer(); *newConnIPtr=0;
-  int work=start;
-  const int *conn=_nodal_connec->getConstPointer();
-  const int *connIndex=_nodal_connec_index->getConstPointer();
-  for(int i=0;i<newNbOfCells;i++,newConnIPtr++,work+=step)
-    {
-      if(work>=0 && work<ncell)
-        {
-          newConnIPtr[1]=newConnIPtr[0]+connIndex[work+1]-connIndex[work];
-        }
-      else
-        {
-          std::ostringstream oss; oss << "MEDCouplingUMesh::buildPartOfMySelfKeepCoordsSlice : On pos #" << i << " input cell id =" << work << " should be in [0," << ncell << ") !";
-          throw INTERP_KERNEL::Exception(oss.str());
-        }
-    }
-  MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(newConnIPtr[0],1);
-  int *newConnPtr=newConn->getPointer();
-  std::set<INTERP_KERNEL::NormalizedCellType> types;
-  work=start;
-  for(int i=0;i<newNbOfCells;i++,newConnIPtr++,work+=step)
-    {
-      types.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[work]]);
-      newConnPtr=std::copy(conn+connIndex[work],conn+connIndex[work+1],newConnPtr);
-    }
-  ret->setConnectivity(newConn,newConnI,false);
-  ret->_types=types;
-  ret->copyTinyInfoFrom(this);
-  return ret.retn();
-}
 
-/*!
- * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf.
- * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ).
- * The return newly allocated mesh will share the same coordinates as \a this.
- */
-MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
-{
-  checkConnectivityFullyDefined();
-  int ncell=getNumberOfCells();
-  MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
-  ret->_mesh_dim=_mesh_dim;
-  ret->setCoords(_coords);
-  std::size_t nbOfElemsRet=std::distance(begin,end);
-  int *connIndexRet=(int *)malloc((nbOfElemsRet+1)*sizeof(int));
-  connIndexRet[0]=0;
-  const int *conn=_nodal_connec->getConstPointer();
-  const int *connIndex=_nodal_connec_index->getConstPointer();
-  int newNbring=0;
-  for(const int *work=begin;work!=end;work++,newNbring++)
-    {
-      if(*work>=0 && *work<ncell)
-        connIndexRet[newNbring+1]=connIndexRet[newNbring]+connIndex[*work+1]-connIndex[*work];
-      else
-        {
-          free(connIndexRet);
-          std::ostringstream oss; oss << "MEDCouplingUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
-          throw INTERP_KERNEL::Exception(oss.str());
-        }
-    }
-  int *connRet=(int *)malloc(connIndexRet[nbOfElemsRet]*sizeof(int));
-  int *connRetWork=connRet;
-  std::set<INTERP_KERNEL::NormalizedCellType> types;
-  for(const int *work=begin;work!=end;work++)
-    {
-      types.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*work]]);
-      connRetWork=std::copy(conn+connIndex[*work],conn+connIndex[*work+1],connRetWork);
-    }
-  MCAuto<DataArrayInt> connRetArr=DataArrayInt::New();
-  connRetArr->useArray(connRet,true,C_DEALLOC,connIndexRet[nbOfElemsRet],1);
-  MCAuto<DataArrayInt> connIndexRetArr=DataArrayInt::New();
-  connIndexRetArr->useArray(connIndexRet,true,C_DEALLOC,(int)nbOfElemsRet+1,1);
-  ret->setConnectivity(connRetArr,connIndexRetArr,false);
-  ret->_types=types;
-  ret->copyTinyInfoFrom(this);
-  return ret.retn();
-}
 
 /*!
  * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this
@@ -4344,77 +3954,6 @@ DataArrayDouble *MEDCouplingUMesh::distanceToPoints(const DataArrayDouble *pts,
 
 /// @cond INTERNAL
 
-/*!
- * \param [in] pt the start pointer (included) of the coordinates of the point
- * \param [in] cellIdsBg the start pointer (included) of cellIds
- * \param [in] cellIdsEnd the end pointer (excluded) of cellIds
- * \param [in] nc nodal connectivity
- * \param [in] ncI nodal connectivity index
- * \param [in,out] ret0 the min distance between \a this and the external input point
- * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned.
- * \sa MEDCouplingUMesh::distanceToPoint, MEDCouplingUMesh::distanceToPoints
- */
-void MEDCouplingUMesh::DistanceToPoint3DSurfAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId)
-{
-  cellId=-1;
-  ret0=std::numeric_limits<double>::max();
-  for(const int *zeCell=cellIdsBg;zeCell!=cellIdsEnd;zeCell++)
-    {
-      switch((INTERP_KERNEL::NormalizedCellType)nc[ncI[*zeCell]])
-      {
-        case INTERP_KERNEL::NORM_TRI3:
-          {
-            double tmp=INTERP_KERNEL::DistanceFromPtToTriInSpaceDim3(pt,coords+3*nc[ncI[*zeCell]+1],coords+3*nc[ncI[*zeCell]+2],coords+3*nc[ncI[*zeCell]+3]);
-            if(tmp<ret0)
-              { ret0=tmp; cellId=*zeCell; }
-            break;
-          }
-        case INTERP_KERNEL::NORM_QUAD4:
-        case INTERP_KERNEL::NORM_POLYGON:
-          {
-            double tmp=INTERP_KERNEL::DistanceFromPtToPolygonInSpaceDim3(pt,nc+ncI[*zeCell]+1,nc+ncI[*zeCell+1],coords);
-            if(tmp<ret0)
-              { ret0=tmp; cellId=*zeCell; }
-            break;
-          }
-        default:
-          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint3DSurfAlg : not managed cell type ! Supporting TRI3, QUAD4 and POLYGON !");
-      }
-    }
-}
-
-/*!
- * \param [in] pt the start pointer (included) of the coordinates of the point
- * \param [in] cellIdsBg the start pointer (included) of cellIds
- * \param [in] cellIdsEnd the end pointer (excluded) of cellIds
- * \param [in] nc nodal connectivity
- * \param [in] ncI nodal connectivity index
- * \param [in,out] ret0 the min distance between \a this and the external input point
- * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned.
- * \sa MEDCouplingUMesh::distanceToPoint, MEDCouplingUMesh::distanceToPoints
- */
-void MEDCouplingUMesh::DistanceToPoint2DCurveAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId)
-{
-  cellId=-1;
-  ret0=std::numeric_limits<double>::max();
-  for(const int *zeCell=cellIdsBg;zeCell!=cellIdsEnd;zeCell++)
-    {
-      switch((INTERP_KERNEL::NormalizedCellType)nc[ncI[*zeCell]])
-      {
-        case INTERP_KERNEL::NORM_SEG2:
-          {
-            std::size_t uselessEntry=0;
-            double tmp=INTERP_KERNEL::SquareDistanceFromPtToSegInSpaceDim2(pt,coords+2*nc[ncI[*zeCell]+1],coords+2*nc[ncI[*zeCell]+2],uselessEntry);
-            tmp=sqrt(tmp);
-            if(tmp<ret0)
-              { ret0=tmp; cellId=*zeCell; }
-            break;
-          }
-        default:
-          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint2DCurveAlg : not managed cell type ! Supporting SEG2 !");
-      }
-    }
-}
 /// @endcond
 
 /*!
@@ -4467,271 +4006,48 @@ void MEDCouplingUMesh::getCellsContainingPoint(const double *pos, double eps, st
   elts.clear(); elts.insert(elts.end(),eltsUg->begin(),eltsUg->end());
 }
 
-/// @cond INTERNAL
-
-namespace MEDCoupling
+/*!
+ * Finds cells in contact with several balls (i.e. points with precision).
+ * This method is an extension of getCellContainingPoint() and
+ * getCellsContainingPoint() for the case of multiple points.
+ * For speed reasons, the INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6 and INTERP_KERNEL::NORM_QUAD8 cells are considered as convex cells to detect if a point is IN or OUT.
+ * If it is not the case, please change their types to INTERP_KERNEL::NORM_POLYGON or INTERP_KERNEL::NORM_QPOLYG before invoking this method.
+ *  \param [in] pos - an array of coordinates of points in full interlace mode :
+ *         X0,Y0,Z0,X1,Y1,Z1,... Size of the array must be \a
+ *         this->getSpaceDimension() * \a nbOfPoints 
+ *  \param [in] nbOfPoints - number of points to locate within \a this mesh.
+ *  \param [in] eps - radius of balls (i.e. the precision).
+ *  \param [out] elts - vector returning ids of found cells.
+ *  \param [out] eltsIndex - an array, of length \a nbOfPoints + 1,
+ *         dividing cell ids in \a elts into groups each referring to one
+ *         point. Its every element (except the last one) is an index pointing to the
+ *         first id of a group of cells. For example cells in contact with the *i*-th
+ *         point are described by following range of indices:
+ *         [ \a eltsIndex[ *i* ], \a eltsIndex[ *i*+1 ] ) and the cell ids are
+ *         \a elts[ \a eltsIndex[ *i* ]], \a elts[ \a eltsIndex[ *i* ] + 1 ], ...
+ *         Number of cells in contact with the *i*-th point is
+ *         \a eltsIndex[ *i*+1 ] - \a eltsIndex[ *i* ].
+ *  \throw If the coordinates array is not set.
+ *  \throw If \a this->getMeshDimension() != \a this->getSpaceDimension().
+ *
+ *  \if ENABLE_EXAMPLES
+ *  \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".<br>
+ *  \ref  py_mcumesh_getCellsContainingPoints "Here is a Python example".
+ *  \endif
+ */
+void MEDCouplingUMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps,
+                                                MCAuto<DataArrayInt>& elts, MCAuto<DataArrayInt>& eltsIndex) const
 {
-  template<const int SPACEDIMM>
-  class DummyClsMCUG
-  {
-  public:
-    static const int MY_SPACEDIM=SPACEDIMM;
-    static const int MY_MESHDIM=8;
-    typedef int MyConnType;
-    static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE;
-    // begin
-    // useless, but for windows compilation ...
-    const double* getCoordinatesPtr() const { return 0; }
-    const int* getConnectivityPtr() const { return 0; }
-    const int* getConnectivityIndexPtr() const { return 0; }
-    INTERP_KERNEL::NormalizedCellType getTypeOfElement(int) const { return (INTERP_KERNEL::NormalizedCellType)0; }
-    // end
-  };
-
-  INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge2(INTERP_KERNEL::NormalizedCellType typ, const int *bg, const double *coords2D, std::map< MCAuto<INTERP_KERNEL::Node>,int>& m)
-  {
-    INTERP_KERNEL::Edge *ret(0);
-    MCAuto<INTERP_KERNEL::Node> n0(new INTERP_KERNEL::Node(coords2D[2*bg[0]],coords2D[2*bg[0]+1])),n1(new INTERP_KERNEL::Node(coords2D[2*bg[1]],coords2D[2*bg[1]+1]));
-    m[n0]=bg[0]; m[n1]=bg[1];
-    switch(typ)
+  int spaceDim=getSpaceDimension();
+  int mDim=getMeshDimension();
+  if(spaceDim==3)
     {
-      case INTERP_KERNEL::NORM_SEG2:
+      if(mDim==3)
         {
-          ret=new INTERP_KERNEL::EdgeLin(n0,n1);
-          break;
+          const double *coords=_coords->getConstPointer();
+          getCellsContainingPointsAlg<3>(coords,pos,nbOfPoints,eps,elts,eltsIndex);
         }
-      case INTERP_KERNEL::NORM_SEG3:
-        {
-          INTERP_KERNEL::Node *n2(new INTERP_KERNEL::Node(coords2D[2*bg[2]],coords2D[2*bg[2]+1])); m[n2]=bg[2];
-          INTERP_KERNEL::EdgeLin *e1(new INTERP_KERNEL::EdgeLin(n0,n2)),*e2(new INTERP_KERNEL::EdgeLin(n2,n1));
-          INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
-          // is the SEG3 degenerated, and thus can be reduced to a SEG2?
-          bool colinearity(inters.areColinears());
-          delete e1; delete e2;
-          if(colinearity)
-            { ret=new INTERP_KERNEL::EdgeLin(n0,n1); }
-          else
-            { ret=new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1); }
-          break;
-        }
-      default:
-        throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge2 : Expecting a mesh with spaceDim==2 and meshDim==1 !");
-    }
-    return ret;
-  }
-
-  INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge(INTERP_KERNEL::NormalizedCellType typ, std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >& mapp2, const int *bg)
-  {
-    INTERP_KERNEL::Edge *ret=0;
-    switch(typ)
-    {
-      case INTERP_KERNEL::NORM_SEG2:
-        {
-          ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[1]].first);
-          break;
-        }
-      case INTERP_KERNEL::NORM_SEG3:
-        {
-          INTERP_KERNEL::EdgeLin *e1=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[2]].first);
-          INTERP_KERNEL::EdgeLin *e2=new INTERP_KERNEL::EdgeLin(mapp2[bg[2]].first,mapp2[bg[1]].first);
-          INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
-          // is the SEG3 degenerated, and thus can be reduced to a SEG2?
-          bool colinearity=inters.areColinears();
-          delete e1; delete e2;
-          if(colinearity)
-            ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[1]].first);
-          else
-            ret=new INTERP_KERNEL::EdgeArcCircle(mapp2[bg[0]].first,mapp2[bg[2]].first,mapp2[bg[1]].first);
-          mapp2[bg[2]].second=false;
-          break;
-        }
-      default:
-        throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge : Expecting a mesh with spaceDim==2 and meshDim==1 !");
-    }
-    return ret;
-  }
-
-  /*!
-   * This method creates a sub mesh in Geometric2D DS. The sub mesh is composed by the sub set of cells in 'candidates' taken from
-   * the global mesh 'mDesc'.
-   * The input mesh 'mDesc' must be so that mDim==1 and spaceDim==2.
-   * 'mapp' returns a mapping between local numbering in submesh (represented by a Node*) and the global node numbering in 'mDesc'.
-   */
-  INTERP_KERNEL::QuadraticPolygon *MEDCouplingUMeshBuildQPFromMesh(const MEDCouplingUMesh *mDesc, const std::vector<int>& candidates,
-                                                                   std::map<INTERP_KERNEL::Node *,int>& mapp)
-  {
-    mapp.clear();
-    std::map<int, std::pair<INTERP_KERNEL::Node *,bool> > mapp2;//bool is for a flag specifying if node is boundary (true) or only a middle for SEG3.
-    const double *coo=mDesc->getCoords()->getConstPointer();
-    const int *c=mDesc->getNodalConnectivity()->getConstPointer();
-    const int *cI=mDesc->getNodalConnectivityIndex()->getConstPointer();
-    std::set<int> s;
-    for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
-      s.insert(c+cI[*it]+1,c+cI[(*it)+1]);
-    for(std::set<int>::const_iterator it2=s.begin();it2!=s.end();it2++)
-      {
-        INTERP_KERNEL::Node *n=new INTERP_KERNEL::Node(coo[2*(*it2)],coo[2*(*it2)+1]);
-        mapp2[*it2]=std::pair<INTERP_KERNEL::Node *,bool>(n,true);
-      }
-    INTERP_KERNEL::QuadraticPolygon *ret=new INTERP_KERNEL::QuadraticPolygon;
-    for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
-      {
-        INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)c[cI[*it]];
-        ret->pushBack(MEDCouplingUMeshBuildQPFromEdge(typ,mapp2,c+cI[*it]+1));
-      }
-    for(std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >::const_iterator it2=mapp2.begin();it2!=mapp2.end();it2++)
-      {
-        if((*it2).second.second)
-          mapp[(*it2).second.first]=(*it2).first;
-        ((*it2).second.first)->decrRef();
-      }
-    return ret;
-  }
-
-  INTERP_KERNEL::Node *MEDCouplingUMeshBuildQPNode(int nodeId, const double *coo1, int offset1, const double *coo2, int offset2, const std::vector<double>& addCoo)
-  {
-    if(nodeId>=offset2)
-      {
-        int locId=nodeId-offset2;
-        return new INTERP_KERNEL::Node(addCoo[2*locId],addCoo[2*locId+1]);
-      }
-    if(nodeId>=offset1)
-      {
-        int locId=nodeId-offset1;
-        return new INTERP_KERNEL::Node(coo2[2*locId],coo2[2*locId+1]);
-      }
-    return new INTERP_KERNEL::Node(coo1[2*nodeId],coo1[2*nodeId+1]);
-  }
-
-  /**
-   * Construct a mapping between set of Nodes and the standart MEDCoupling connectivity format (c, cI).
-   */
-  void MEDCouplingUMeshBuildQPFromMesh3(const double *coo1, int offset1, const double *coo2, int offset2, const std::vector<double>& addCoo,
-                                        const int *desc1Bg, const int *desc1End, const std::vector<std::vector<int> >& intesctEdges1,
-                                        /*output*/std::map<INTERP_KERNEL::Node *,int>& mapp, std::map<int,INTERP_KERNEL::Node *>& mappRev)
-  {
-    for(const int *desc1=desc1Bg;desc1!=desc1End;desc1++)
-      {
-        int eltId1=abs(*desc1)-1;
-        for(std::vector<int>::const_iterator it1=intesctEdges1[eltId1].begin();it1!=intesctEdges1[eltId1].end();it1++)
-          {
-            std::map<int,INTERP_KERNEL::Node *>::const_iterator it=mappRev.find(*it1);
-            if(it==mappRev.end())
-              {
-                INTERP_KERNEL::Node *node=MEDCouplingUMeshBuildQPNode(*it1,coo1,offset1,coo2,offset2,addCoo);
-                mapp[node]=*it1;
-                mappRev[*it1]=node;
-              }
-          }
-      }
-  }
-}
-
-/// @endcond
-
-template<int SPACEDIM>
-void MEDCouplingUMesh::getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints,
-                                                   double eps, MCAuto<DataArrayInt>& elts, MCAuto<DataArrayInt>& eltsIndex) const
-{
-  elts=DataArrayInt::New(); eltsIndex=DataArrayInt::New(); eltsIndex->alloc(nbOfPoints+1,1); eltsIndex->setIJ(0,0,0); elts->alloc(0,1);
-  int *eltsIndexPtr(eltsIndex->getPointer());
-  MCAuto<DataArrayDouble> bboxArr(getBoundingBoxForBBTree(eps));
-  const double *bbox(bboxArr->begin());
-  int nbOfCells=getNumberOfCells();
-  const int *conn=_nodal_connec->getConstPointer();
-  const int *connI=_nodal_connec_index->getConstPointer();
-  double bb[2*SPACEDIM];
-  BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbOfCells,-eps);
-  for(int i=0;i<nbOfPoints;i++)
-    {
-      eltsIndexPtr[i+1]=eltsIndexPtr[i];
-      for(int j=0;j<SPACEDIM;j++)
-        {
-          bb[2*j]=pos[SPACEDIM*i+j];
-          bb[2*j+1]=pos[SPACEDIM*i+j];
-        }
-      std::vector<int> candidates;
-      myTree.getIntersectingElems(bb,candidates);
-      for(std::vector<int>::const_iterator iter=candidates.begin();iter!=candidates.end();iter++)
-        {
-          int sz(connI[(*iter)+1]-connI[*iter]-1);
-          INTERP_KERNEL::NormalizedCellType ct((INTERP_KERNEL::NormalizedCellType)conn[connI[*iter]]);
-          bool status(false);
-          if(ct!=INTERP_KERNEL::NORM_POLYGON && ct!=INTERP_KERNEL::NORM_QPOLYG)
-            status=INTERP_KERNEL::PointLocatorAlgos<DummyClsMCUG<SPACEDIM> >::isElementContainsPoint(pos+i*SPACEDIM,ct,coords,conn+connI[*iter]+1,sz,eps);
-          else
-            {
-              if(SPACEDIM!=2)
-                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellsContainingPointsAlg : not implemented yet for POLYGON and QPOLYGON in spaceDim 3 !");
-              INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
-              INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
-              std::vector<INTERP_KERNEL::Node *> nodes(sz);
-              INTERP_KERNEL::QuadraticPolygon *pol(0);
-              for(int j=0;j<sz;j++)
-                {
-                  int nodeId(conn[connI[*iter]+1+j]);
-                  nodes[j]=new INTERP_KERNEL::Node(coords[nodeId*SPACEDIM],coords[nodeId*SPACEDIM+1]);
-                }
-              if(!INTERP_KERNEL::CellModel::GetCellModel(ct).isQuadratic())
-                pol=INTERP_KERNEL::QuadraticPolygon::BuildLinearPolygon(nodes);
-              else
-                pol=INTERP_KERNEL::QuadraticPolygon::BuildArcCirclePolygon(nodes);
-              INTERP_KERNEL::Node *n(new INTERP_KERNEL::Node(pos[i*SPACEDIM],pos[i*SPACEDIM+1]));
-              double a(0.),b(0.),c(0.);
-              a=pol->normalizeMe(b,c); n->applySimilarity(b,c,a);
-              status=pol->isInOrOut2(n);
-              delete pol; n->decrRef();
-            }
-          if(status)
-            {
-              eltsIndexPtr[i+1]++;
-              elts->pushBackSilent(*iter);
-            }
-        }
-    }
-}
-/*!
- * Finds cells in contact with several balls (i.e. points with precision).
- * This method is an extension of getCellContainingPoint() and
- * getCellsContainingPoint() for the case of multiple points.
- * For speed reasons, the INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6 and INTERP_KERNEL::NORM_QUAD8 cells are considered as convex cells to detect if a point is IN or OUT.
- * If it is not the case, please change their types to INTERP_KERNEL::NORM_POLYGON or INTERP_KERNEL::NORM_QPOLYG before invoking this method.
- *  \param [in] pos - an array of coordinates of points in full interlace mode :
- *         X0,Y0,Z0,X1,Y1,Z1,... Size of the array must be \a
- *         this->getSpaceDimension() * \a nbOfPoints 
- *  \param [in] nbOfPoints - number of points to locate within \a this mesh.
- *  \param [in] eps - radius of balls (i.e. the precision).
- *  \param [out] elts - vector returning ids of found cells.
- *  \param [out] eltsIndex - an array, of length \a nbOfPoints + 1,
- *         dividing cell ids in \a elts into groups each referring to one
- *         point. Its every element (except the last one) is an index pointing to the
- *         first id of a group of cells. For example cells in contact with the *i*-th
- *         point are described by following range of indices:
- *         [ \a eltsIndex[ *i* ], \a eltsIndex[ *i*+1 ] ) and the cell ids are
- *         \a elts[ \a eltsIndex[ *i* ]], \a elts[ \a eltsIndex[ *i* ] + 1 ], ...
- *         Number of cells in contact with the *i*-th point is
- *         \a eltsIndex[ *i*+1 ] - \a eltsIndex[ *i* ].
- *  \throw If the coordinates array is not set.
- *  \throw If \a this->getMeshDimension() != \a this->getSpaceDimension().
- *
- *  \if ENABLE_EXAMPLES
- *  \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".<br>
- *  \ref  py_mcumesh_getCellsContainingPoints "Here is a Python example".
- *  \endif
- */
-void MEDCouplingUMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps,
-                                                MCAuto<DataArrayInt>& elts, MCAuto<DataArrayInt>& eltsIndex) const
-{
-  int spaceDim=getSpaceDimension();
-  int mDim=getMeshDimension();
-  if(spaceDim==3)
-    {
-      if(mDim==3)
-        {
-          const double *coords=_coords->getConstPointer();
-          getCellsContainingPointsAlg<3>(coords,pos,nbOfPoints,eps,elts,eltsIndex);
-        }
-      /*else if(mDim==2)
+      /*else if(mDim==2)
         {
 
         }*/
@@ -4901,296 +4217,6 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMesh(const MEDCouplingUMesh *me
   return ret.retn();
 }
 
-/*!
- * This method works on a 3D curve linear mesh that is to say (meshDim==1 and spaceDim==3).
- * If it is not the case an exception will be thrown.
- * This method is non const because the coordinate of \a this can be appended with some new points issued from
- * intersection of plane defined by ('origin','vec').
- * This method has one in/out parameter : 'cut3DCurve'.
- * Param 'cut3DCurve' is expected to be of size 'this->getNumberOfCells()'. For each i in [0,'this->getNumberOfCells()')
- * if cut3DCurve[i]==-2, it means that for cell #i in \a this nothing has been detected previously.
- * if cut3DCurve[i]==-1, it means that cell#i has been already detected to be fully part of plane defined by ('origin','vec').
- * This method will throw an exception if \a this contains a non linear segment.
- */
-void MEDCouplingUMesh::split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector<int>& cut3DCurve)
-{
-  checkFullyDefined();
-  if(getMeshDimension()!=1 || getSpaceDimension()!=3)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane works on umeshes with meshdim equal to 1 and spaceDim equal to 3 !");
-  int ncells=getNumberOfCells();
-  int nnodes=getNumberOfNodes();
-  double vec2[3],vec3[3],vec4[3];
-  double normm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
-  if(normm<1e-6)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane : parameter 'vec' should have a norm2 greater than 1e-6 !");
-  vec2[0]=vec[0]/normm; vec2[1]=vec[1]/normm; vec2[2]=vec[2]/normm;
-  const int *conn=_nodal_connec->getConstPointer();
-  const int *connI=_nodal_connec_index->getConstPointer();
-  const double *coo=_coords->getConstPointer();
-  std::vector<double> addCoo;
-  for(int i=0;i<ncells;i++)
-    {
-      if(conn[connI[i]]==(int)INTERP_KERNEL::NORM_SEG2)
-        {
-          if(cut3DCurve[i]==-2)
-            {
-              int st=conn[connI[i]+1],endd=conn[connI[i]+2];
-              vec3[0]=coo[3*endd]-coo[3*st]; vec3[1]=coo[3*endd+1]-coo[3*st+1]; vec3[2]=coo[3*endd+2]-coo[3*st+2];
-              double normm2=sqrt(vec3[0]*vec3[0]+vec3[1]*vec3[1]+vec3[2]*vec3[2]);
-              double colin=std::abs((vec3[0]*vec2[0]+vec3[1]*vec2[1]+vec3[2]*vec2[2])/normm2);
-              if(colin>eps)//if colin<=eps -> current SEG2 is colinear to the input plane
-                {
-                  const double *st2=coo+3*st;
-                  vec4[0]=st2[0]-origin[0]; vec4[1]=st2[1]-origin[1]; vec4[2]=st2[2]-origin[2];
-                  double pos=-(vec4[0]*vec2[0]+vec4[1]*vec2[1]+vec4[2]*vec2[2])/((vec3[0]*vec2[0]+vec3[1]*vec2[1]+vec3[2]*vec2[2]));
-                  if(pos>eps && pos<1-eps)
-                    {
-                      int nNode=((int)addCoo.size())/3;
-                      vec4[0]=st2[0]+pos*vec3[0]; vec4[1]=st2[1]+pos*vec3[1]; vec4[2]=st2[2]+pos*vec3[2];
-                      addCoo.insert(addCoo.end(),vec4,vec4+3);
-                      cut3DCurve[i]=nnodes+nNode;
-                    }
-                }
-            }
-        }
-      else
-        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane : this method is only available for linear cell (NORM_SEG2) !");
-    }
-  if(!addCoo.empty())
-    {
-      int newNbOfNodes=nnodes+((int)addCoo.size())/3;
-      MCAuto<DataArrayDouble> coo2=DataArrayDouble::New();
-      coo2->alloc(newNbOfNodes,3);
-      double *tmp=coo2->getPointer();
-      tmp=std::copy(_coords->begin(),_coords->end(),tmp);
-      std::copy(addCoo.begin(),addCoo.end(),tmp);
-      DataArrayDouble::SetArrayIn(coo2,_coords);
-    }
-}
-
-/*!
- * This method incarnates the policy 0 for MEDCouplingUMesh::buildExtrudedMesh method.
- * \param mesh1D is the input 1D mesh used for translation computation.
- * \return newCoords new coords filled by this method. 
- */
-DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const
-{
-  int oldNbOfNodes=getNumberOfNodes();
-  int nbOf1DCells=mesh1D->getNumberOfCells();
-  int spaceDim=getSpaceDimension();
-  DataArrayDouble *ret=DataArrayDouble::New();
-  std::vector<bool> isQuads;
-  int nbOfLevsInVec=isQuad?2*nbOf1DCells+1:nbOf1DCells+1;
-  ret->alloc(oldNbOfNodes*nbOfLevsInVec,spaceDim);
-  double *retPtr=ret->getPointer();
-  const double *coords=getCoords()->getConstPointer();
-  double *work=std::copy(coords,coords+spaceDim*oldNbOfNodes,retPtr);
-  std::vector<int> v;
-  std::vector<double> c;
-  double vec[3];
-  v.reserve(3);
-  c.reserve(6);
-  for(int i=0;i<nbOf1DCells;i++)
-    {
-      v.resize(0);
-      mesh1D->getNodeIdsOfCell(i,v);
-      c.resize(0);
-      mesh1D->getCoordinatesOfNode(v[isQuad?2:1],c);
-      mesh1D->getCoordinatesOfNode(v[0],c);
-      std::transform(c.begin(),c.begin()+spaceDim,c.begin()+spaceDim,vec,std::minus<double>());
-      for(int j=0;j<oldNbOfNodes;j++)
-        work=std::transform(vec,vec+spaceDim,retPtr+spaceDim*(i*oldNbOfNodes+j),work,std::plus<double>());
-      if(isQuad)
-        {
-          c.resize(0);
-          mesh1D->getCoordinatesOfNode(v[1],c);
-          mesh1D->getCoordinatesOfNode(v[0],c);
-          std::transform(c.begin(),c.begin()+spaceDim,c.begin()+spaceDim,vec,std::minus<double>());
-          for(int j=0;j<oldNbOfNodes;j++)
-            work=std::transform(vec,vec+spaceDim,retPtr+spaceDim*(i*oldNbOfNodes+j),work,std::plus<double>());
-        }
-    }
-  ret->copyStringInfoFrom(*getCoords());
-  return ret;
-}
-
-/*!
- * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method.
- * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation.
- * \return newCoords new coords filled by this method. 
- */
-DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const
-{
-  if(mesh1D->getSpaceDimension()==2)
-    return fillExtCoordsUsingTranslAndAutoRotation2D(mesh1D,isQuad);
-  if(mesh1D->getSpaceDimension()==3)
-    return fillExtCoordsUsingTranslAndAutoRotation3D(mesh1D,isQuad);
-  throw INTERP_KERNEL::Exception("Not implemented rotation and translation alg. for spacedim other than 2 and 3 !");
-}
-
-/*!
- * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method.
- * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation.
- * \return newCoords new coords filled by this method. 
- */
-DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const
-{
-  if(isQuad)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D : not implemented for quadratic cells !");
-  int oldNbOfNodes=getNumberOfNodes();
-  int nbOf1DCells=mesh1D->getNumberOfCells();
-  if(nbOf1DCells<2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D : impossible to detect any angle of rotation ! Change extrusion policy 1->0 !");
-  MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
-  int nbOfLevsInVec=nbOf1DCells+1;
-  ret->alloc(oldNbOfNodes*nbOfLevsInVec,2);
-  double *retPtr=ret->getPointer();
-  retPtr=std::copy(getCoords()->getConstPointer(),getCoords()->getConstPointer()+getCoords()->getNbOfElems(),retPtr);
-  MCAuto<MEDCouplingUMesh> tmp=MEDCouplingUMesh::New();
-  MCAuto<DataArrayDouble> tmp2=getCoords()->deepCopy();
-  tmp->setCoords(tmp2);
-  const double *coo1D=mesh1D->getCoords()->getConstPointer();
-  const int *conn1D=mesh1D->getNodalConnectivity()->getConstPointer();
-  const int *connI1D=mesh1D->getNodalConnectivityIndex()->getConstPointer();
-  for(int i=1;i<nbOfLevsInVec;i++)
-    {
-      const double *begin=coo1D+2*conn1D[connI1D[i-1]+1];
-      const double *end=coo1D+2*conn1D[connI1D[i-1]+2];
-      const double *third=i+1<nbOfLevsInVec?coo1D+2*conn1D[connI1D[i]+2]:coo1D+2*conn1D[connI1D[i-2]+1];
-      const double vec[2]={end[0]-begin[0],end[1]-begin[1]};
-      tmp->translate(vec);
-      double tmp3[2],radius,alpha,alpha0;
-      const double *p0=i+1<nbOfLevsInVec?begin:third;
-      const double *p1=i+1<nbOfLevsInVec?end:begin;
-      const double *p2=i+1<nbOfLevsInVec?third:end;
-      INTERP_KERNEL::EdgeArcCircle::GetArcOfCirclePassingThru(p0,p1,p2,tmp3,radius,alpha,alpha0);
-      double cosangle=i+1<nbOfLevsInVec?(p0[0]-tmp3[0])*(p1[0]-tmp3[0])+(p0[1]-tmp3[1])*(p1[1]-tmp3[1]):(p2[0]-tmp3[0])*(p1[0]-tmp3[0])+(p2[1]-tmp3[1])*(p1[1]-tmp3[1]);
-      double angle=acos(cosangle/(radius*radius));
-      tmp->rotate(end,0,angle);
-      retPtr=std::copy(tmp2->getConstPointer(),tmp2->getConstPointer()+tmp2->getNbOfElems(),retPtr);
-    }
-  return ret.retn();
-}
-
-/*!
- * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method.
- * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation.
- * \return newCoords new coords filled by this method. 
- */
-DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const
-{
-  if(isQuad)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D : not implemented for quadratic cells !");
-  int oldNbOfNodes=getNumberOfNodes();
-  int nbOf1DCells=mesh1D->getNumberOfCells();
-  if(nbOf1DCells<2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D : impossible to detect any angle of rotation ! Change extrusion policy 1->0 !");
-  MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
-  int nbOfLevsInVec=nbOf1DCells+1;
-  ret->alloc(oldNbOfNodes*nbOfLevsInVec,3);
-  double *retPtr=ret->getPointer();
-  retPtr=std::copy(getCoords()->getConstPointer(),getCoords()->getConstPointer()+getCoords()->getNbOfElems(),retPtr);
-  MCAuto<MEDCouplingUMesh> tmp=MEDCouplingUMesh::New();
-  MCAuto<DataArrayDouble> tmp2=getCoords()->deepCopy();
-  tmp->setCoords(tmp2);
-  const double *coo1D=mesh1D->getCoords()->getConstPointer();
-  const int *conn1D=mesh1D->getNodalConnectivity()->getConstPointer();
-  const int *connI1D=mesh1D->getNodalConnectivityIndex()->getConstPointer();
-  for(int i=1;i<nbOfLevsInVec;i++)
-    {
-      const double *begin=coo1D+3*conn1D[connI1D[i-1]+1];
-      const double *end=coo1D+3*conn1D[connI1D[i-1]+2];
-      const double *third=i+1<nbOfLevsInVec?coo1D+3*conn1D[connI1D[i]+2]:coo1D+3*conn1D[connI1D[i-2]+1];
-      const double vec[3]={end[0]-begin[0],end[1]-begin[1],end[2]-begin[2]};
-      tmp->translate(vec);
-      double tmp3[2],radius,alpha,alpha0;
-      const double *p0=i+1<nbOfLevsInVec?begin:third;
-      const double *p1=i+1<nbOfLevsInVec?end:begin;
-      const double *p2=i+1<nbOfLevsInVec?third:end;
-      double vecPlane[3]={
-        (p1[1]-p0[1])*(p2[2]-p1[2])-(p1[2]-p0[2])*(p2[1]-p1[1]),
-        (p1[2]-p0[2])*(p2[0]-p1[0])-(p1[0]-p0[0])*(p2[2]-p1[2]),
-        (p1[0]-p0[0])*(p2[1]-p1[1])-(p1[1]-p0[1])*(p2[0]-p1[0]),
-      };
-      double norm=sqrt(vecPlane[0]*vecPlane[0]+vecPlane[1]*vecPlane[1]+vecPlane[2]*vecPlane[2]);
-      if(norm>1.e-7)
-        {
-          vecPlane[0]/=norm; vecPlane[1]/=norm; vecPlane[2]/=norm;
-          double norm2=sqrt(vecPlane[0]*vecPlane[0]+vecPlane[1]*vecPlane[1]);
-          double vec2[2]={vecPlane[1]/norm2,-vecPlane[0]/norm2};
-          double s2=norm2;
-          double c2=cos(asin(s2));
-          double m[3][3]={
-            {vec2[0]*vec2[0]*(1-c2)+c2, vec2[0]*vec2[1]*(1-c2), vec2[1]*s2},
-            {vec2[0]*vec2[1]*(1-c2), vec2[1]*vec2[1]*(1-c2)+c2, -vec2[0]*s2},
-            {-vec2[1]*s2, vec2[0]*s2, c2}
-          };
-          double p0r[3]={m[0][0]*p0[0]+m[0][1]*p0[1]+m[0][2]*p0[2], m[1][0]*p0[0]+m[1][1]*p0[1]+m[1][2]*p0[2], m[2][0]*p0[0]+m[2][1]*p0[1]+m[2][2]*p0[2]};
-          double p1r[3]={m[0][0]*p1[0]+m[0][1]*p1[1]+m[0][2]*p1[2], m[1][0]*p1[0]+m[1][1]*p1[1]+m[1][2]*p1[2], m[2][0]*p1[0]+m[2][1]*p1[1]+m[2][2]*p1[2]};
-          double p2r[3]={m[0][0]*p2[0]+m[0][1]*p2[1]+m[0][2]*p2[2], m[1][0]*p2[0]+m[1][1]*p2[1]+m[1][2]*p2[2], m[2][0]*p2[0]+m[2][1]*p2[1]+m[2][2]*p2[2]};
-          INTERP_KERNEL::EdgeArcCircle::GetArcOfCirclePassingThru(p0r,p1r,p2r,tmp3,radius,alpha,alpha0);
-          double cosangle=i+1<nbOfLevsInVec?(p0r[0]-tmp3[0])*(p1r[0]-tmp3[0])+(p0r[1]-tmp3[1])*(p1r[1]-tmp3[1]):(p2r[0]-tmp3[0])*(p1r[0]-tmp3[0])+(p2r[1]-tmp3[1])*(p1r[1]-tmp3[1]);
-          double angle=acos(cosangle/(radius*radius));
-          tmp->rotate(end,vecPlane,angle);
-        }
-      retPtr=std::copy(tmp2->getConstPointer(),tmp2->getConstPointer()+tmp2->getNbOfElems(),retPtr);
-    }
-  return ret.retn();
-}
-
-/*!
- * This method is private because not easy to use for end user. This method is const contrary to
- * MEDCouplingUMesh::buildExtrudedMesh method because this->_coords are expected to contain
- * the coords sorted slice by slice.
- * \param isQuad specifies presence of quadratic cells.
- */
-MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const
-{
-  int nbOf1DCells(getNumberOfNodes()/nbOfNodesOf1Lev-1);
-  int nbOf2DCells(getNumberOfCells());
-  int nbOf3DCells(nbOf2DCells*nbOf1DCells);
-  MEDCouplingUMesh *ret(MEDCouplingUMesh::New("Extruded",getMeshDimension()+1));
-  const int *conn(_nodal_connec->begin()),*connI(_nodal_connec_index->begin());
-  MCAuto<DataArrayInt> newConn(DataArrayInt::New()),newConnI(DataArrayInt::New());
-  newConnI->alloc(nbOf3DCells+1,1);
-  int *newConnIPtr(newConnI->getPointer());
-  *newConnIPtr++=0;
-  std::vector<int> newc;
-  for(int j=0;j<nbOf2DCells;j++)
-    {
-      AppendExtrudedCell(conn+connI[j],conn+connI[j+1],nbOfNodesOf1Lev,isQuad,newc);
-      *newConnIPtr++=(int)newc.size();
-    }
-  newConn->alloc((int)(newc.size())*nbOf1DCells,1);
-  int *newConnPtr(newConn->getPointer());
-  int deltaPerLev(isQuad?2*nbOfNodesOf1Lev:nbOfNodesOf1Lev);
-  newConnIPtr=newConnI->getPointer();
-  for(int iz=0;iz<nbOf1DCells;iz++)
-    {
-      if(iz!=0)
-        std::transform(newConnIPtr+1,newConnIPtr+1+nbOf2DCells,newConnIPtr+1+iz*nbOf2DCells,std::bind2nd(std::plus<int>(),newConnIPtr[iz*nbOf2DCells]));
-      const int *posOfTypeOfCell(newConnIPtr);
-      for(std::vector<int>::const_iterator iter=newc.begin();iter!=newc.end();iter++,newConnPtr++)
-        {
-          int icell((int)(iter-newc.begin()));//std::distance unfortunately cannot been called here in C++98
-          if(icell!=*posOfTypeOfCell)
-            {
-              if(*iter!=-1)
-                *newConnPtr=(*iter)+iz*deltaPerLev;
-              else
-                *newConnPtr=-1;
-            }
-          else
-            {
-              *newConnPtr=*iter;
-              posOfTypeOfCell++;
-            }
-        }
-    }
-  ret->setConnectivity(newConn,newConnI,true);
-  ret->setCoords(getCoords());
-  return ret;
-}
 
 /*!
  * Checks if \a this mesh is constituted by only quadratic cells.
@@ -5447,290 +4473,48 @@ void MEDCouplingUMesh::splitSomeEdgesOf2DMesh(const DataArrayInt *nodeIdsToAdd,
 }
 #endif
 
+
 /*!
- * Implementes \a conversionType 0 for meshes with meshDim = 1, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
- * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
- * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic.
+ * Divides every cell of \a this mesh into simplices (triangles in 2D and tetrahedra in 3D).
+ * In addition, returns an array mapping new cells to old ones. <br>
+ * This method typically increases the number of cells in \a this mesh
+ * but the number of nodes remains \b unchanged.
+ * That's why the 3D splitting policies
+ * INTERP_KERNEL::GENERAL_24 and INTERP_KERNEL::GENERAL_48 are not available here.
+ *  \param [in] policy - specifies a pattern used for splitting.
+ * The semantic of \a policy is:
+ * - 0 - to split QUAD4 by cutting it along 0-2 diagonal (for 2D mesh only).
+ * - 1 - to split QUAD4 by cutting it along 1-3 diagonal (for 2D mesh only).
+ * - INTERP_KERNEL::PLANAR_FACE_5 - to split HEXA8  into 5 TETRA4 (for 3D mesh only - see INTERP_KERNEL::SplittingPolicy for an image).
+ * - INTERP_KERNEL::PLANAR_FACE_6 - to split HEXA8  into 6 TETRA4 (for 3D mesh only - see INTERP_KERNEL::SplittingPolicy for an image).
+ *
+ *
+ *  \return DataArrayInt * - a new instance of DataArrayInt holding, for each new cell,
+ *          an id of old cell producing it. The caller is to delete this array using
+ *         decrRef() as it is no more needed.
+ *
+ *  \throw If \a policy is 0 or 1 and \a this->getMeshDimension() != 2.
+ *  \throw If \a policy is INTERP_KERNEL::PLANAR_FACE_5 or INTERP_KERNEL::PLANAR_FACE_6
+ *          and \a this->getMeshDimension() != 3. 
+ *  \throw If \a policy is not one of the four discussed above.
+ *  \throw If the nodal connectivity of cells is not defined.
+ * \sa MEDCouplingUMesh::tetrahedrize, MEDCoupling1SGTUMesh::sortHexa8EachOther
  */
-DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic1D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
+DataArrayInt *MEDCouplingUMesh::simplexize(int policy)
 {
-  MCAuto<DataArrayDouble> bary=computeCellCenterOfMass();
-  MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
-  MCAuto<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
-  MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
-  int nbOfCells=getNumberOfCells();
-  int nbOfNodes=getNumberOfNodes();
-  const int *cPtr=_nodal_connec->begin();
-  const int *icPtr=_nodal_connec_index->begin();
-  int lastVal=0,offset=nbOfNodes;
-  for(int i=0;i<nbOfCells;i++,icPtr++)
-    {
-      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
-      if(type==INTERP_KERNEL::NORM_SEG2)
-        {
-          types.insert(INTERP_KERNEL::NORM_SEG3);
-          newConn->pushBackSilent((int)INTERP_KERNEL::NORM_SEG3);
-          newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[0]+3);
-          newConn->pushBackSilent(offset++);
-          lastVal+=4;
-          newConnI->pushBackSilent(lastVal);
-          ret->pushBackSilent(i);
-        }
-      else
-        {
-          types.insert(type);
-          lastVal+=(icPtr[1]-icPtr[0]);
-          newConnI->pushBackSilent(lastVal);
-          newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
-        }
-    }
-  MCAuto<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end());
-  coords=DataArrayDouble::Aggregate(getCoords(),tmp); conn=newConn.retn(); connI=newConnI.retn();
-  return ret.retn();
-}
-
-DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
-{
-  MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
-  MCAuto<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
-  MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
-  //
-  const int *descPtr(desc->begin()),*descIPtr(descI->begin());
-  DataArrayInt *conn1D=0,*conn1DI=0;
-  std::set<INTERP_KERNEL::NormalizedCellType> types1D;
-  DataArrayDouble *coordsTmp=0;
-  MCAuto<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0;
-  MCAuto<DataArrayDouble> coordsTmpSafe(coordsTmp);
-  MCAuto<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI);
-  const int *c1DPtr=conn1D->begin();
-  const int *c1DIPtr=conn1DI->begin();
-  int nbOfCells=getNumberOfCells();
-  const int *cPtr=_nodal_connec->begin();
-  const int *icPtr=_nodal_connec_index->begin();
-  int lastVal=0;
-  for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++)
-    {
-      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
-      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
-      if(!cm.isQuadratic())
-        {
-          INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType();
-          types.insert(typ2); newConn->pushBackSilent(typ2);
-          newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]);
-          for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++)
-            newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]);
-          lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0]);
-          newConnI->pushBackSilent(lastVal);
-          ret->pushBackSilent(i);
-        }
-      else
-        {
-          types.insert(typ);
-          lastVal+=(icPtr[1]-icPtr[0]);
-          newConnI->pushBackSilent(lastVal);
-          newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
-        }
-    }
-  conn=newConn.retn(); connI=newConnI.retn(); coords=coordsTmpSafe.retn();
-  return ret.retn();
-}
-
-/*!
- * Implementes \a conversionType 0 for meshes with meshDim = 2, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
- * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
- * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic.
- */
-DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
-{
-  MCAuto<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
-  MCAuto<MEDCouplingUMesh> m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0;
-  return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types);
-}
-
-DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
-{
-  MCAuto<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
-  MCAuto<MEDCouplingUMesh> m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0;
-  //
-  MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
-  MCAuto<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
-  MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
-  //
-  MCAuto<DataArrayDouble> bary=computeCellCenterOfMass();
-  const int *descPtr(desc->begin()),*descIPtr(descI->begin());
-  DataArrayInt *conn1D=0,*conn1DI=0;
-  std::set<INTERP_KERNEL::NormalizedCellType> types1D;
-  DataArrayDouble *coordsTmp=0;
-  MCAuto<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0;
-  MCAuto<DataArrayDouble> coordsTmpSafe(coordsTmp);
-  MCAuto<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI);
-  const int *c1DPtr=conn1D->begin();
-  const int *c1DIPtr=conn1DI->begin();
-  int nbOfCells=getNumberOfCells();
-  const int *cPtr=_nodal_connec->begin();
-  const int *icPtr=_nodal_connec_index->begin();
-  int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples();
-  for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++)
-    {
-      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
-      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
-      if(!cm.isQuadratic())
-        {
-          INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType2();
-          types.insert(typ2); newConn->pushBackSilent(typ2);
-          newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]);
-          for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++)
-            newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]);
-          newConn->pushBackSilent(offset+ret->getNumberOfTuples());
-          lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+1;
-          newConnI->pushBackSilent(lastVal);
-          ret->pushBackSilent(i);
-        }
-      else
-        {
-          types.insert(typ);
-          lastVal+=(icPtr[1]-icPtr[0]);
-          newConnI->pushBackSilent(lastVal);
-          newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
-        }
-    }
-  MCAuto<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end());
-  coords=DataArrayDouble::Aggregate(coordsTmpSafe,tmp); conn=newConn.retn(); connI=newConnI.retn();
-  return ret.retn();
-}
-
-/*!
- * Implementes \a conversionType 0 for meshes with meshDim = 3, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
- * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
- * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic.
- */
-DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
-{
-  MCAuto<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
-  MCAuto<MEDCouplingUMesh> m1D=explode3DMeshTo1D(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0;
-  return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types);
-}
-
-DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
-{
-  MCAuto<DataArrayInt> desc2(DataArrayInt::New()),desc2I(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
-  MCAuto<MEDCouplingUMesh> m2D=buildDescendingConnectivityGen<MinusOneSonsGeneratorBiQuadratic>(desc2,desc2I,tmp2,tmp3,MEDCouplingFastNbrer); tmp2=0; tmp3=0;
-  MCAuto<DataArrayInt> desc1(DataArrayInt::New()),desc1I(DataArrayInt::New()),tmp4(DataArrayInt::New()),tmp5(DataArrayInt::New());
-  MCAuto<MEDCouplingUMesh> m1D=explode3DMeshTo1D(desc1,desc1I,tmp4,tmp5); tmp4=0; tmp5=0;
-  //
-  MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
-  MCAuto<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
-  MCAuto<DataArrayInt> ret=DataArrayInt::New(),ret2=DataArrayInt::New(); ret->alloc(0,1); ret2->alloc(0,1);
-  //
-  MCAuto<DataArrayDouble> bary=computeCellCenterOfMass();
-  const int *descPtr(desc1->begin()),*descIPtr(desc1I->begin()),*desc2Ptr(desc2->begin()),*desc2IPtr(desc2I->begin());
-  DataArrayInt *conn1D=0,*conn1DI=0,*conn2D=0,*conn2DI=0;
-  std::set<INTERP_KERNEL::NormalizedCellType> types1D,types2D;
-  DataArrayDouble *coordsTmp=0,*coordsTmp2=0;
-  MCAuto<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=DataArrayInt::New(); ret1D->alloc(0,1);
-  MCAuto<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI);
-  MCAuto<DataArrayDouble> coordsTmpSafe(coordsTmp);
-  MCAuto<DataArrayInt> ret2D=m2D->convertLinearCellsToQuadratic2D1(conn2D,conn2DI,coordsTmp2,types2D); ret2D=DataArrayInt::New(); ret2D->alloc(0,1);
-  MCAuto<DataArrayDouble> coordsTmp2Safe(coordsTmp2);
-  MCAuto<DataArrayInt> conn2DSafe(conn2D),conn2DISafe(conn2DI);
-  const int *c1DPtr=conn1D->begin(),*c1DIPtr=conn1DI->begin(),*c2DPtr=conn2D->begin(),*c2DIPtr=conn2DI->begin();
-  int nbOfCells=getNumberOfCells();
-  const int *cPtr=_nodal_connec->begin();
-  const int *icPtr=_nodal_connec_index->begin();
-  int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples();
-  for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++,desc2IPtr++)
-    {
-      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
-      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
-      if(!cm.isQuadratic())
-        {
-          INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType2();
-          if(typ2==INTERP_KERNEL::NORM_ERROR)
-            {
-              std::ostringstream oss; oss << "MEDCouplingUMesh::convertLinearCellsToQuadratic3D1 : On cell #" << i << " the linear cell type does not support advanced quadratization !";
-              throw INTERP_KERNEL::Exception(oss.str());
-            }
-          types.insert(typ2); newConn->pushBackSilent(typ2);
-          newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]);
-          for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++)
-            newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]);
-          for(const int *d=desc2Ptr+desc2IPtr[0];d!=desc2Ptr+desc2IPtr[1];d++)
-            {
-              int nodeId2=c2DPtr[c2DIPtr[(*d)+1]-1];
-              int tmpPos=newConn->getNumberOfTuples();
-              newConn->pushBackSilent(nodeId2);
-              ret2D->pushBackSilent(nodeId2); ret1D->pushBackSilent(tmpPos);
-            }
-          newConn->pushBackSilent(offset+ret->getNumberOfTuples());
-          lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+(desc2IPtr[1]-desc2IPtr[0])+1;
-          newConnI->pushBackSilent(lastVal);
-          ret->pushBackSilent(i);
-        }
-      else
-        {
-          types.insert(typ);
-          lastVal+=(icPtr[1]-icPtr[0]);
-          newConnI->pushBackSilent(lastVal);
-          newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
-        }
-    }
-  MCAuto<DataArrayInt> diffRet2D=ret2D->getDifferentValues();
-  MCAuto<DataArrayInt> o2nRet2D=diffRet2D->invertArrayN2O2O2N(coordsTmp2Safe->getNumberOfTuples());
-  coordsTmp2Safe=coordsTmp2Safe->selectByTupleId(diffRet2D->begin(),diffRet2D->end());
-  MCAuto<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end());
-  std::vector<const DataArrayDouble *> v(3); v[0]=coordsTmpSafe; v[1]=coordsTmp2Safe; v[2]=tmp;
-  int *c=newConn->getPointer();
-  const int *cI(newConnI->begin());
-  for(const int *elt=ret1D->begin();elt!=ret1D->end();elt++)
-    c[*elt]=o2nRet2D->getIJ(c[*elt],0)+offset;
-  offset=coordsTmp2Safe->getNumberOfTuples();
-  for(const int *elt=ret->begin();elt!=ret->end();elt++)
-    c[cI[(*elt)+1]-1]+=offset;
-  coords=DataArrayDouble::Aggregate(v); conn=newConn.retn(); connI=newConnI.retn();
-  return ret.retn();
-}
-
-/*!
- * Divides every cell of \a this mesh into simplices (triangles in 2D and tetrahedra in 3D).
- * In addition, returns an array mapping new cells to old ones. <br>
- * This method typically increases the number of cells in \a this mesh
- * but the number of nodes remains \b unchanged.
- * That's why the 3D splitting policies
- * INTERP_KERNEL::GENERAL_24 and INTERP_KERNEL::GENERAL_48 are not available here.
- *  \param [in] policy - specifies a pattern used for splitting.
- * The semantic of \a policy is:
- * - 0 - to split QUAD4 by cutting it along 0-2 diagonal (for 2D mesh only).
- * - 1 - to split QUAD4 by cutting it along 1-3 diagonal (for 2D mesh only).
- * - INTERP_KERNEL::PLANAR_FACE_5 - to split HEXA8  into 5 TETRA4 (for 3D mesh only - see INTERP_KERNEL::SplittingPolicy for an image).
- * - INTERP_KERNEL::PLANAR_FACE_6 - to split HEXA8  into 6 TETRA4 (for 3D mesh only - see INTERP_KERNEL::SplittingPolicy for an image).
- *
- *
- *  \return DataArrayInt * - a new instance of DataArrayInt holding, for each new cell,
- *          an id of old cell producing it. The caller is to delete this array using
- *         decrRef() as it is no more needed.
- *
- *  \throw If \a policy is 0 or 1 and \a this->getMeshDimension() != 2.
- *  \throw If \a policy is INTERP_KERNEL::PLANAR_FACE_5 or INTERP_KERNEL::PLANAR_FACE_6
- *          and \a this->getMeshDimension() != 3. 
- *  \throw If \a policy is not one of the four discussed above.
- *  \throw If the nodal connectivity of cells is not defined.
- * \sa MEDCouplingUMesh::tetrahedrize, MEDCoupling1SGTUMesh::sortHexa8EachOther
- */
-DataArrayInt *MEDCouplingUMesh::simplexize(int policy)
-{
-  switch(policy)
-  {
-    case 0:
-      return simplexizePol0();
-    case 1:
-      return simplexizePol1();
-    case (int) INTERP_KERNEL::PLANAR_FACE_5:
-        return simplexizePlanarFace5();
-    case (int) INTERP_KERNEL::PLANAR_FACE_6:
-        return simplexizePlanarFace6();
-    default:
-      throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexize : unrecognized policy ! Must be :\n  - 0 or 1 (only available for meshdim=2) \n  - PLANAR_FACE_5, PLANAR_FACE_6  (only for meshdim=3)");
-  }
+  switch(policy)
+  {
+    case 0:
+      return simplexizePol0();
+    case 1:
+      return simplexizePol1();
+    case (int) INTERP_KERNEL::PLANAR_FACE_5:
+        return simplexizePlanarFace5();
+    case (int) INTERP_KERNEL::PLANAR_FACE_6:
+        return simplexizePlanarFace6();
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexize : unrecognized policy ! Must be :\n  - 0 or 1 (only available for meshdim=2) \n  - PLANAR_FACE_5, PLANAR_FACE_6  (only for meshdim=3)");
+  }
 }
 
 /*!
@@ -5765,552 +4549,151 @@ bool MEDCouplingUMesh::areOnlySimplexCells() const
   return true;
 }
 
+
+
 /*!
- * This method implements policy 0 of virtual method MEDCoupling::MEDCouplingUMesh::simplexize.
+ * Converts degenerated 2D or 3D linear cells of \a this mesh into cells of simpler
+ * type. For example an INTERP_KERNEL::NORM_QUAD4 cell having only three unique nodes in
+ * its connectivity is transformed into an INTERP_KERNEL::NORM_TRI3 cell. This method
+ * does \b not perform geometrical checks and checks only nodal connectivity of cells,
+ * so it can be useful to call mergeNodes() before calling this method.
+ *  \throw If \a this->getMeshDimension() <= 1.
+ *  \throw If the coordinates array is not set.
+ *  \throw If the nodal connectivity of cells is not defined.
  */
-DataArrayInt *MEDCouplingUMesh::simplexizePol0()
+void MEDCouplingUMesh::convertDegeneratedCells()
 {
-  checkConnectivityFullyDefined();
-  if(getMeshDimension()!=2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !");
+  checkFullyDefined();
+  if(getMeshDimension()<=1)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertDegeneratedCells works on umeshes with meshdim equals to 2 or 3 !");
   int nbOfCells=getNumberOfCells();
-  MCAuto<DataArrayInt> ret=DataArrayInt::New();
-  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4);
-  ret->alloc(nbOfCells+nbOfCutCells,1);
-  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
-  int *retPt=ret->getPointer();
-  MCAuto<DataArrayInt> newConn=DataArrayInt::New();
-  MCAuto<DataArrayInt> newConnI=DataArrayInt::New();
-  newConnI->alloc(nbOfCells+nbOfCutCells+1,1);
-  newConn->alloc(getNodalConnectivityArrayLen()+3*nbOfCutCells,1);
-  int *pt=newConn->getPointer();
-  int *ptI=newConnI->getPointer();
-  ptI[0]=0;
-  const int *oldc=_nodal_connec->begin();
-  const int *ci=_nodal_connec_index->begin();
-  for(int i=0;i<nbOfCells;i++,ci++)
-    {
-      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_QUAD4)
-        {
-          const int tmp[8]={(int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+2],oldc[ci[0]+3],
-            (int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+3],oldc[ci[0]+4]};
-          pt=std::copy(tmp,tmp+8,pt);
-          ptI[1]=ptI[0]+4;
-          ptI[2]=ptI[0]+8;
-          *retPt++=i;
-          *retPt++=i;
-          ptI+=2;
-        }
-      else
-        {
-          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
-          ptI[1]=ptI[0]+ci[1]-ci[0];
-          ptI++;
-          *retPt++=i;
-        }
+  if(nbOfCells<1)
+    return ;
+  int initMeshLgth=getNodalConnectivityArrayLen();
+  int *conn=_nodal_connec->getPointer();
+  int *index=_nodal_connec_index->getPointer();
+  int posOfCurCell=0;
+  int newPos=0;
+  int lgthOfCurCell;
+  for(int i=0;i<nbOfCells;i++)
+    {
+      lgthOfCurCell=index[i+1]-posOfCurCell;
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[posOfCurCell];
+      int newLgth;
+      INTERP_KERNEL::NormalizedCellType newType=INTERP_KERNEL::CellSimplify::simplifyDegeneratedCell(type,conn+posOfCurCell+1,lgthOfCurCell-1,
+                                                                                                     conn+newPos+1,newLgth);
+      conn[newPos]=newType;
+      newPos+=newLgth+1;
+      posOfCurCell=index[i+1];
+      index[i+1]=newPos;
     }
-  _nodal_connec->decrRef();
-  _nodal_connec=newConn.retn();
-  _nodal_connec_index->decrRef();
-  _nodal_connec_index=newConnI.retn();
+  if(newPos!=initMeshLgth)
+    _nodal_connec->reAlloc(newPos);
   computeTypes();
-  updateTime();
-  return ret.retn();
 }
 
 /*!
- * This method implements policy 1 of virtual method MEDCoupling::MEDCouplingUMesh::simplexize.
+ * Finds incorrectly oriented cells of this 2D mesh in 3D space.
+ * A cell is considered to be oriented correctly if an angle between its
+ * normal vector and a given vector is less than \c PI / \c 2.
+ *  \param [in] vec - 3 components of the vector specifying the correct orientation of
+ *         cells. 
+ *  \param [in] polyOnly - if \c true, only polygons are checked, else, all cells are
+ *         checked.
+ *  \param [in,out] cells - a vector returning ids of incorrectly oriented cells. It
+ *         is not cleared before filling in.
+ *  \throw If \a this->getMeshDimension() != 2.
+ *  \throw If \a this->getSpaceDimension() != 3.
+ *
+ *  \if ENABLE_EXAMPLES
+ *  \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".<br>
+ *  \ref  py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example".
+ *  \endif
  */
-DataArrayInt *MEDCouplingUMesh::simplexizePol1()
+void MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector<int>& cells) const
 {
-  checkConnectivityFullyDefined();
-  if(getMeshDimension()!=2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !");
+  if(getMeshDimension()!=2 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply are2DCellsNotCorrectlyOriented on it : must be meshDim==2 and spaceDim==3 !");
   int nbOfCells=getNumberOfCells();
-  MCAuto<DataArrayInt> ret=DataArrayInt::New();
-  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4);
-  ret->alloc(nbOfCells+nbOfCutCells,1);
-  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
-  int *retPt=ret->getPointer();
-  MCAuto<DataArrayInt> newConn=DataArrayInt::New();
-  MCAuto<DataArrayInt> newConnI=DataArrayInt::New();
-  newConnI->alloc(nbOfCells+nbOfCutCells+1,1);
-  newConn->alloc(getNodalConnectivityArrayLen()+3*nbOfCutCells,1);
-  int *pt=newConn->getPointer();
-  int *ptI=newConnI->getPointer();
-  ptI[0]=0;
-  const int *oldc=_nodal_connec->begin();
-  const int *ci=_nodal_connec_index->begin();
-  for(int i=0;i<nbOfCells;i++,ci++)
-    {
-      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_QUAD4)
-        {
-          const int tmp[8]={(int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+2],oldc[ci[0]+4],
-            (int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+2],oldc[ci[0]+3],oldc[ci[0]+4]};
-          pt=std::copy(tmp,tmp+8,pt);
-          ptI[1]=ptI[0]+4;
-          ptI[2]=ptI[0]+8;
-          *retPt++=i;
-          *retPt++=i;
-          ptI+=2;
-        }
-      else
+  const int *conn=_nodal_connec->begin();
+  const int *connI=_nodal_connec_index->begin();
+  const double *coordsPtr=_coords->begin();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
+      if(!polyOnly || (type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG))
         {
-          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
-          ptI[1]=ptI[0]+ci[1]-ci[0];
-          ptI++;
-          *retPt++=i;
+          bool isQuadratic=INTERP_KERNEL::CellModel::GetCellModel(type).isQuadratic();
+          if(!IsPolygonWellOriented(isQuadratic,vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+            cells.push_back(i);
         }
     }
-  _nodal_connec->decrRef();
-  _nodal_connec=newConn.retn();
-  _nodal_connec_index->decrRef();
-  _nodal_connec_index=newConnI.retn();
-  computeTypes();
-  updateTime();
-  return ret.retn();
 }
 
 /*!
- * This method implements policy INTERP_KERNEL::PLANAR_FACE_5 of virtual method MEDCoupling::MEDCouplingUMesh::simplexize.
+ * Reverse connectivity of 2D cells whose orientation is not correct. A cell is
+ * considered to be oriented correctly if an angle between its normal vector and a
+ * given vector is less than \c PI / \c 2. 
+ *  \param [in] vec - 3 components of the vector specifying the correct orientation of
+ *         cells. 
+ *  \param [in] polyOnly - if \c true, only polygons are checked, else, all cells are
+ *         checked.
+ *  \throw If \a this->getMeshDimension() != 2.
+ *  \throw If \a this->getSpaceDimension() != 3.
+ *
+ *  \if ENABLE_EXAMPLES
+ *  \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".<br>
+ *  \ref  py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example".
+ *  \endif
+ *
+ *  \sa changeOrientationOfCells
  */
-DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace5()
+void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly)
 {
-  checkConnectivityFullyDefined();
-  if(getMeshDimension()!=3)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace5 : this policy is only available for mesh with meshdim == 3 !");
-  int nbOfCells=getNumberOfCells();
-  MCAuto<DataArrayInt> ret=DataArrayInt::New();
-  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8);
-  ret->alloc(nbOfCells+4*nbOfCutCells,1);
-  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
-  int *retPt=ret->getPointer();
-  MCAuto<DataArrayInt> newConn=DataArrayInt::New();
-  MCAuto<DataArrayInt> newConnI=DataArrayInt::New();
-  newConnI->alloc(nbOfCells+4*nbOfCutCells+1,1);
-  newConn->alloc(getNodalConnectivityArrayLen()+16*nbOfCutCells,1);//21
-  int *pt=newConn->getPointer();
-  int *ptI=newConnI->getPointer();
-  ptI[0]=0;
-  const int *oldc=_nodal_connec->begin();
-  const int *ci=_nodal_connec_index->begin();
-  for(int i=0;i<nbOfCells;i++,ci++)
-    {
-      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_HEXA8)
+  if(getMeshDimension()!=2 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectly2DCells on it : must be meshDim==2 and spaceDim==3 !");
+  int nbOfCells(getNumberOfCells()),*conn(_nodal_connec->getPointer());
+  const int *connI(_nodal_connec_index->begin());
+  const double *coordsPtr(_coords->begin());
+  bool isModified(false);
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
+      if(!polyOnly || (type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG))
         {
-          for(int j=0;j<5;j++,pt+=5,ptI++)
+          const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
+          bool isQuadratic(cm.isQuadratic());
+          if(!IsPolygonWellOriented(isQuadratic,vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
             {
-              pt[0]=(int)INTERP_KERNEL::NORM_TETRA4;
-              pt[1]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+0]+1]; pt[2]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+1]+1]; pt[3]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+2]+1]; pt[4]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+3]+1];
-              *retPt++=i;
-              ptI[1]=ptI[0]+5;
+              isModified=true;
+              cm.changeOrientationOf2D(conn+connI[i]+1,(unsigned int)(connI[i+1]-connI[i]-1));
             }
         }
-      else
-        {
-          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
-          ptI[1]=ptI[0]+ci[1]-ci[0];
-          ptI++;
-          *retPt++=i;
-        }
     }
-  _nodal_connec->decrRef();
-  _nodal_connec=newConn.retn();
-  _nodal_connec_index->decrRef();
-  _nodal_connec_index=newConnI.retn();
-  computeTypes();
+  if(isModified)
+    _nodal_connec->declareAsNew();
   updateTime();
-  return ret.retn();
 }
 
 /*!
- * This method implements policy INTERP_KERNEL::PLANAR_FACE_6 of virtual method MEDCoupling::MEDCouplingUMesh::simplexize.
+ * This method change the orientation of cells in \a this without any consideration of coordinates. Only connectivity is impacted.
+ *
+ * \sa orientCorrectly2DCells
  */
-DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace6()
+void MEDCouplingUMesh::changeOrientationOfCells()
 {
-  checkConnectivityFullyDefined();
-  if(getMeshDimension()!=3)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace6 : this policy is only available for mesh with meshdim == 3 !");
-  int nbOfCells=getNumberOfCells();
-  MCAuto<DataArrayInt> ret=DataArrayInt::New();
-  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8);
-  ret->alloc(nbOfCells+5*nbOfCutCells,1);
-  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
-  int *retPt=ret->getPointer();
-  MCAuto<DataArrayInt> newConn=DataArrayInt::New();
-  MCAuto<DataArrayInt> newConnI=DataArrayInt::New();
-  newConnI->alloc(nbOfCells+5*nbOfCutCells+1,1);
-  newConn->alloc(getNodalConnectivityArrayLen()+21*nbOfCutCells,1);
-  int *pt=newConn->getPointer();
-  int *ptI=newConnI->getPointer();
-  ptI[0]=0;
-  const int *oldc=_nodal_connec->begin();
-  const int *ci=_nodal_connec_index->begin();
-  for(int i=0;i<nbOfCells;i++,ci++)
-    {
-      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_HEXA8)
+  int mdim(getMeshDimension());
+  if(mdim!=2 && mdim!=1)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply changeOrientationOfCells on it : must be meshDim==2 or meshDim==1 !");
+  int nbOfCells(getNumberOfCells()),*conn(_nodal_connec->getPointer());
+  const int *connI(_nodal_connec_index->begin());
+  if(mdim==2)
+    {//2D
+      for(int i=0;i<nbOfCells;i++)
         {
-          for(int j=0;j<6;j++,pt+=5,ptI++)
-            {
-              pt[0]=(int)INTERP_KERNEL::NORM_TETRA4;
-              pt[1]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+0]+1]; pt[2]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+1]+1]; pt[3]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+2]+1]; pt[4]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+3]+1];
-              *retPt++=i;
-              ptI[1]=ptI[0]+5;
-            }
-        }
-      else
-        {
-          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
-          ptI[1]=ptI[0]+ci[1]-ci[0];
-          ptI++;
-          *retPt++=i;
-        }
-    }
-  _nodal_connec->decrRef();
-  _nodal_connec=newConn.retn();
-  _nodal_connec_index->decrRef();
-  _nodal_connec_index=newConnI.retn();
-  computeTypes();
-  updateTime();
-  return ret.retn();
-}
-
-/*!
- * Tessellates \a this 2D mesh by dividing not straight edges of quadratic faces,
- * so that the number of cells remains the same. Quadratic faces are converted to
- * polygons. This method works only for 2D meshes in
- * 2D space. If no cells are quadratic (INTERP_KERNEL::NORM_QUAD8,
- * INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QPOLYG ), \a this mesh remains unchanged.
- * \warning This method can lead to a huge amount of nodes if \a eps is very low.
- *  \param [in] eps - specifies the maximal angle (in radians) between 2 sub-edges of
- *         a polylinized edge constituting the input polygon.
- *  \throw If the coordinates array is not set.
- *  \throw If the nodal connectivity of cells is not defined.
- *  \throw If \a this->getMeshDimension() != 2.
- *  \throw If \a this->getSpaceDimension() != 2.
- */
-void MEDCouplingUMesh::tessellate2DInternal(double eps)
-{
-  checkFullyDefined();
-  if(getMeshDimension()!=2 || getSpaceDimension()!=2)  
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DInternal works on umeshes with meshdim equal to 2 and spaceDim equal to 2 too!");
-  double epsa=fabs(eps);
-  if(epsa<std::numeric_limits<double>::min())
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DInternal : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !");
-  MCAuto<DataArrayInt> desc1(DataArrayInt::New()),descIndx1(DataArrayInt::New()),revDesc1(DataArrayInt::New()),revDescIndx1(DataArrayInt::New());
-  MCAuto<MEDCouplingUMesh> mDesc(buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1));
-  revDesc1=0; revDescIndx1=0;
-  mDesc->tessellate2D(eps);
-  subDivide2DMesh(mDesc->_nodal_connec->begin(),mDesc->_nodal_connec_index->begin(),desc1->begin(),descIndx1->begin());
-  setCoords(mDesc->getCoords());
-}
-
-/*!
- * Tessellates \a this 1D mesh in 2D space by dividing not straight quadratic edges.
- * \warning This method can lead to a huge amount of nodes if \a eps is very low.
- *  \param [in] eps - specifies the maximal angle (in radian) between 2 sub-edges of
- *         a sub-divided edge.
- *  \throw If the coordinates array is not set.
- *  \throw If the nodal connectivity of cells is not defined.
- *  \throw If \a this->getMeshDimension() != 1.
- *  \throw If \a this->getSpaceDimension() != 2.
- */
-void MEDCouplingUMesh::tessellate2DCurveInternal(double eps)
-{
-  checkFullyDefined();
-  if(getMeshDimension()!=1 || getSpaceDimension()!=2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurveInternal works on umeshes with meshdim equal to 1 and spaceDim equal to 2 too!");
-  double epsa=fabs(eps);
-  if(epsa<std::numeric_limits<double>::min())
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurveInternal : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !");
-  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1.e-10;
-  int nbCells=getNumberOfCells();
-  int nbNodes=getNumberOfNodes();
-  const int *conn=_nodal_connec->begin();
-  const int *connI=_nodal_connec_index->begin();
-  const double *coords=_coords->begin();
-  std::vector<double> addCoo;
-  std::vector<int> newConn;//no direct DataArrayInt because interface with Geometric2D
-  MCAuto<DataArrayInt> newConnI(DataArrayInt::New());
-  newConnI->alloc(nbCells+1,1);
-  int *newConnIPtr=newConnI->getPointer();
-  *newConnIPtr=0;
-  int tmp1[3];
-  INTERP_KERNEL::Node *tmp2[3];
-  std::set<INTERP_KERNEL::NormalizedCellType> types;
-  for(int i=0;i<nbCells;i++,newConnIPtr++)
-    {
-      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
-      if(cm.isQuadratic())
-        {//assert(connI[i+1]-connI[i]-1==3)
-          tmp1[0]=conn[connI[i]+1+0]; tmp1[1]=conn[connI[i]+1+1]; tmp1[2]=conn[connI[i]+1+2];
-          tmp2[0]=new INTERP_KERNEL::Node(coords[2*tmp1[0]],coords[2*tmp1[0]+1]);
-          tmp2[1]=new INTERP_KERNEL::Node(coords[2*tmp1[1]],coords[2*tmp1[1]+1]);
-          tmp2[2]=new INTERP_KERNEL::Node(coords[2*tmp1[2]],coords[2*tmp1[2]+1]);
-          INTERP_KERNEL::EdgeArcCircle *eac=INTERP_KERNEL::EdgeArcCircle::BuildFromNodes(tmp2[0],tmp2[2],tmp2[1]);
-          if(eac)
-            {
-              eac->tesselate(tmp1,nbNodes,epsa,newConn,addCoo);
-              types.insert((INTERP_KERNEL::NormalizedCellType)newConn[newConnIPtr[0]]);
-              delete eac;
-              newConnIPtr[1]=(int)newConn.size();
-            }
-          else
-            {
-              types.insert(INTERP_KERNEL::NORM_SEG2);
-              newConn.push_back(INTERP_KERNEL::NORM_SEG2);
-              newConn.insert(newConn.end(),conn+connI[i]+1,conn+connI[i]+3);
-              newConnIPtr[1]=newConnIPtr[0]+3;
-            }
-        }
-      else
-        {
-          types.insert((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
-          newConn.insert(newConn.end(),conn+connI[i],conn+connI[i+1]);
-          newConnIPtr[1]=newConnIPtr[0]+3;
-        }
-    }
-  if(addCoo.empty() && ((int)newConn.size())==_nodal_connec->getNumberOfTuples())//nothing happens during tessellation : no update needed
-    return ;
-  _types=types;
-  DataArrayInt::SetArrayIn(newConnI,_nodal_connec_index);
-  MCAuto<DataArrayInt> newConnArr=DataArrayInt::New();
-  newConnArr->alloc((int)newConn.size(),1);
-  std::copy(newConn.begin(),newConn.end(),newConnArr->getPointer());
-  DataArrayInt::SetArrayIn(newConnArr,_nodal_connec);
-  MCAuto<DataArrayDouble> newCoords=DataArrayDouble::New();
-  newCoords->alloc(nbNodes+((int)addCoo.size())/2,2);
-  double *work=std::copy(_coords->begin(),_coords->end(),newCoords->getPointer());
-  std::copy(addCoo.begin(),addCoo.end(),work);
-  DataArrayDouble::SetArrayIn(newCoords,_coords);
-  updateTime();
-}
-
-/*!
- * This private method is used to subdivide edges of a mesh with meshdim==2. If \a this has no a meshdim equal to 2 an exception will be thrown.
- * This method completly ignore coordinates.
- * \param nodeSubdived is the nodal connectivity of subdivision of edges
- * \param nodeIndxSubdived is the nodal connectivity index of subdivision of edges
- * \param desc is descending connectivity in format specified in MEDCouplingUMesh::buildDescendingConnectivity2
- * \param descIndex is descending connectivity index in format specified in MEDCouplingUMesh::buildDescendingConnectivity2
- */
-void MEDCouplingUMesh::subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex)
-{
-  checkFullyDefined();
-  if(getMeshDimension()!=2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::subDivide2DMesh : works only on umesh with meshdim==2 !");
-  int nbOfCells=getNumberOfCells();
-  int *connI=_nodal_connec_index->getPointer();
-  int newConnLgth=0;
-  for(int i=0;i<nbOfCells;i++,connI++)
-    {
-      int offset=descIndex[i];
-      int nbOfEdges=descIndex[i+1]-offset;
-      //
-      bool ddirect=desc[offset+nbOfEdges-1]>0;
-      int eedgeId=std::abs(desc[offset+nbOfEdges-1])-1;
-      int ref=ddirect?nodeSubdived[nodeIndxSubdived[eedgeId+1]-1]:nodeSubdived[nodeIndxSubdived[eedgeId]+1];
-      for(int j=0;j<nbOfEdges;j++)
-        {
-          bool direct=desc[offset+j]>0;
-          int edgeId=std::abs(desc[offset+j])-1;
-          if(!INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodeSubdived[nodeIndxSubdived[edgeId]]).isQuadratic())
-            {
-              int id1=nodeSubdived[nodeIndxSubdived[edgeId]+1];
-              int id2=nodeSubdived[nodeIndxSubdived[edgeId+1]-1];
-              int ref2=direct?id1:id2;
-              if(ref==ref2)
-                {
-                  int nbOfSubNodes=nodeIndxSubdived[edgeId+1]-nodeIndxSubdived[edgeId]-1;
-                  newConnLgth+=nbOfSubNodes-1;
-                  ref=direct?id2:id1;
-                }
-              else
-                {
-                  std::ostringstream oss; oss << "MEDCouplingUMesh::subDivide2DMesh : On polygon #" << i << " edgeid #" << j << " subedges mismatch : end subedge k!=start subedge k+1 !";
-                  throw INTERP_KERNEL::Exception(oss.str());
-                }
-            }
-          else
-            {
-              throw INTERP_KERNEL::Exception("MEDCouplingUMesh::subDivide2DMesh : this method only subdivides into linear edges !");
-            }
-        }
-      newConnLgth++;//+1 is for cell type
-      connI[1]=newConnLgth;
-    }
-  //
-  MCAuto<DataArrayInt> newConn=DataArrayInt::New();
-  newConn->alloc(newConnLgth,1);
-  int *work=newConn->getPointer();
-  for(int i=0;i<nbOfCells;i++)
-    {
-      *work++=INTERP_KERNEL::NORM_POLYGON;
-      int offset=descIndex[i];
-      int nbOfEdges=descIndex[i+1]-offset;
-      for(int j=0;j<nbOfEdges;j++)
-        {
-          bool direct=desc[offset+j]>0;
-          int edgeId=std::abs(desc[offset+j])-1;
-          if(direct)
-            work=std::copy(nodeSubdived+nodeIndxSubdived[edgeId]+1,nodeSubdived+nodeIndxSubdived[edgeId+1]-1,work);
-          else
-            {
-              int nbOfSubNodes=nodeIndxSubdived[edgeId+1]-nodeIndxSubdived[edgeId]-1;
-              std::reverse_iterator<const int *> it(nodeSubdived+nodeIndxSubdived[edgeId+1]);
-              work=std::copy(it,it+nbOfSubNodes-1,work);
-            }
-        }
-    }
-  DataArrayInt::SetArrayIn(newConn,_nodal_connec);
-  _types.clear();
-  if(nbOfCells>0)
-    _types.insert(INTERP_KERNEL::NORM_POLYGON);
-}
-
-/*!
- * Converts degenerated 2D or 3D linear cells of \a this mesh into cells of simpler
- * type. For example an INTERP_KERNEL::NORM_QUAD4 cell having only three unique nodes in
- * its connectivity is transformed into an INTERP_KERNEL::NORM_TRI3 cell. This method
- * does \b not perform geometrical checks and checks only nodal connectivity of cells,
- * so it can be useful to call mergeNodes() before calling this method.
- *  \throw If \a this->getMeshDimension() <= 1.
- *  \throw If the coordinates array is not set.
- *  \throw If the nodal connectivity of cells is not defined.
- */
-void MEDCouplingUMesh::convertDegeneratedCells()
-{
-  checkFullyDefined();
-  if(getMeshDimension()<=1)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertDegeneratedCells works on umeshes with meshdim equals to 2 or 3 !");
-  int nbOfCells=getNumberOfCells();
-  if(nbOfCells<1)
-    return ;
-  int initMeshLgth=getNodalConnectivityArrayLen();
-  int *conn=_nodal_connec->getPointer();
-  int *index=_nodal_connec_index->getPointer();
-  int posOfCurCell=0;
-  int newPos=0;
-  int lgthOfCurCell;
-  for(int i=0;i<nbOfCells;i++)
-    {
-      lgthOfCurCell=index[i+1]-posOfCurCell;
-      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[posOfCurCell];
-      int newLgth;
-      INTERP_KERNEL::NormalizedCellType newType=INTERP_KERNEL::CellSimplify::simplifyDegeneratedCell(type,conn+posOfCurCell+1,lgthOfCurCell-1,
-                                                                                                     conn+newPos+1,newLgth);
-      conn[newPos]=newType;
-      newPos+=newLgth+1;
-      posOfCurCell=index[i+1];
-      index[i+1]=newPos;
-    }
-  if(newPos!=initMeshLgth)
-    _nodal_connec->reAlloc(newPos);
-  computeTypes();
-}
-
-/*!
- * Finds incorrectly oriented cells of this 2D mesh in 3D space.
- * A cell is considered to be oriented correctly if an angle between its
- * normal vector and a given vector is less than \c PI / \c 2.
- *  \param [in] vec - 3 components of the vector specifying the correct orientation of
- *         cells. 
- *  \param [in] polyOnly - if \c true, only polygons are checked, else, all cells are
- *         checked.
- *  \param [in,out] cells - a vector returning ids of incorrectly oriented cells. It
- *         is not cleared before filling in.
- *  \throw If \a this->getMeshDimension() != 2.
- *  \throw If \a this->getSpaceDimension() != 3.
- *
- *  \if ENABLE_EXAMPLES
- *  \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".<br>
- *  \ref  py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example".
- *  \endif
- */
-void MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector<int>& cells) const
-{
-  if(getMeshDimension()!=2 || getSpaceDimension()!=3)
-    throw INTERP_KERNEL::Exception("Invalid mesh to apply are2DCellsNotCorrectlyOriented on it : must be meshDim==2 and spaceDim==3 !");
-  int nbOfCells=getNumberOfCells();
-  const int *conn=_nodal_connec->begin();
-  const int *connI=_nodal_connec_index->begin();
-  const double *coordsPtr=_coords->begin();
-  for(int i=0;i<nbOfCells;i++)
-    {
-      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
-      if(!polyOnly || (type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG))
-        {
-          bool isQuadratic=INTERP_KERNEL::CellModel::GetCellModel(type).isQuadratic();
-          if(!IsPolygonWellOriented(isQuadratic,vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
-            cells.push_back(i);
-        }
-    }
-}
-
-/*!
- * Reverse connectivity of 2D cells whose orientation is not correct. A cell is
- * considered to be oriented correctly if an angle between its normal vector and a
- * given vector is less than \c PI / \c 2. 
- *  \param [in] vec - 3 components of the vector specifying the correct orientation of
- *         cells. 
- *  \param [in] polyOnly - if \c true, only polygons are checked, else, all cells are
- *         checked.
- *  \throw If \a this->getMeshDimension() != 2.
- *  \throw If \a this->getSpaceDimension() != 3.
- *
- *  \if ENABLE_EXAMPLES
- *  \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".<br>
- *  \ref  py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example".
- *  \endif
- *
- *  \sa changeOrientationOfCells
- */
-void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly)
-{
-  if(getMeshDimension()!=2 || getSpaceDimension()!=3)
-    throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectly2DCells on it : must be meshDim==2 and spaceDim==3 !");
-  int nbOfCells(getNumberOfCells()),*conn(_nodal_connec->getPointer());
-  const int *connI(_nodal_connec_index->begin());
-  const double *coordsPtr(_coords->begin());
-  bool isModified(false);
-  for(int i=0;i<nbOfCells;i++)
-    {
-      INTERP_KERNEL::NormalizedCellType type((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
-      if(!polyOnly || (type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG))
-        {
-          const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
-          bool isQuadratic(cm.isQuadratic());
-          if(!IsPolygonWellOriented(isQuadratic,vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
-            {
-              isModified=true;
-              cm.changeOrientationOf2D(conn+connI[i]+1,(unsigned int)(connI[i+1]-connI[i]-1));
-            }
-        }
-    }
-  if(isModified)
-    _nodal_connec->declareAsNew();
-  updateTime();
-}
-
-/*!
- * This method change the orientation of cells in \a this without any consideration of coordinates. Only connectivity is impacted.
- *
- * \sa orientCorrectly2DCells
- */
-void MEDCouplingUMesh::changeOrientationOfCells()
-{
-  int mdim(getMeshDimension());
-  if(mdim!=2 && mdim!=1)
-    throw INTERP_KERNEL::Exception("Invalid mesh to apply changeOrientationOfCells on it : must be meshDim==2 or meshDim==1 !");
-  int nbOfCells(getNumberOfCells()),*conn(_nodal_connec->getPointer());
-  const int *connI(_nodal_connec_index->begin());
-  if(mdim==2)
-    {//2D
-      for(int i=0;i<nbOfCells;i++)
-        {
-          INTERP_KERNEL::NormalizedCellType type((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
-          const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
-          cm.changeOrientationOf2D(conn+connI[i]+1,(unsigned int)(connI[i+1]-connI[i]-1));
+          INTERP_KERNEL::NormalizedCellType type((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
+          const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
+          cm.changeOrientationOf2D(conn+connI[i]+1,(unsigned int)(connI[i+1]-connI[i]-1));
         }
     }
   else
@@ -8147,81 +6530,22 @@ MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(const std::vector<const MEDCoup
   return MergeUMeshesLL(aa);
 }
 
-/// @cond INTERNAL
-
-MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesLL(const std::vector<const MEDCouplingUMesh *>& a)
-{
-  if(a.empty())
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::MergeUMeshes : input array must be NON EMPTY !");
-  std::vector<const MEDCouplingUMesh *>::const_iterator it=a.begin();
-  int meshDim=(*it)->getMeshDimension();
-  int nbOfCells=(*it)->getNumberOfCells();
-  int meshLgth=(*it++)->getNodalConnectivityArrayLen();
-  for(;it!=a.end();it++)
-    {
-      if(meshDim!=(*it)->getMeshDimension())
-        throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, MergeUMeshes impossible !");
-      nbOfCells+=(*it)->getNumberOfCells();
-      meshLgth+=(*it)->getNodalConnectivityArrayLen();
-    }
-  std::vector<const MEDCouplingPointSet *> aps(a.size());
-  std::copy(a.begin(),a.end(),aps.begin());
-  MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
-  MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("merge",meshDim);
-  ret->setCoords(pts);
-  MCAuto<DataArrayInt> c=DataArrayInt::New();
-  c->alloc(meshLgth,1);
-  int *cPtr=c->getPointer();
-  MCAuto<DataArrayInt> cI=DataArrayInt::New();
-  cI->alloc(nbOfCells+1,1);
-  int *cIPtr=cI->getPointer();
-  *cIPtr++=0;
-  int offset=0;
-  int offset2=0;
-  for(it=a.begin();it!=a.end();it++)
-    {
-      int curNbOfCell=(*it)->getNumberOfCells();
-      const int *curCI=(*it)->_nodal_connec_index->begin();
-      const int *curC=(*it)->_nodal_connec->begin();
-      cIPtr=std::transform(curCI+1,curCI+curNbOfCell+1,cIPtr,std::bind2nd(std::plus<int>(),offset));
-      for(int j=0;j<curNbOfCell;j++)
-        {
-          const int *src=curC+curCI[j];
-          *cPtr++=*src++;
-          for(;src!=curC+curCI[j+1];src++,cPtr++)
-            {
-              if(*src!=-1)
-                *cPtr=*src+offset2;
-              else
-                *cPtr=-1;
-            }
-        }
-      offset+=curCI[curNbOfCell];
-      offset2+=(*it)->getNumberOfNodes();
-    }
-  //
-  ret->setConnectivity(c,cI,true);
-  return ret.retn();
-}
-
-/// @endcond
-
-/*!
- * Creates a new MEDCouplingUMesh by concatenating cells of two given meshes of same
- * dimension and sharing the node coordinates array.
- * All cells of the first mesh precede all cells of the second mesh
- * within the result mesh. 
- *  \param [in] mesh1 - the first mesh.
- *  \param [in] mesh2 - the second mesh.
- *  \return MEDCouplingUMesh * - the result mesh. It is a new instance of
- *          MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it
- *          is no more needed.
- *  \throw If \a mesh1 == NULL or \a mesh2 == NULL.
- *  \throw If the meshes do not share the node coordinates array.
- *  \throw If \a mesh1->getMeshDimension() < 0 or \a mesh2->getMeshDimension() < 0.
- *  \throw If \a mesh1->getMeshDimension() != \a mesh2->getMeshDimension().
- */
-MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2)
+/*!
+ * Creates a new MEDCouplingUMesh by concatenating cells of two given meshes of same
+ * dimension and sharing the node coordinates array.
+ * All cells of the first mesh precede all cells of the second mesh
+ * within the result mesh.
+ *  \param [in] mesh1 - the first mesh.
+ *  \param [in] mesh2 - the second mesh.
+ *  \return MEDCouplingUMesh * - the result mesh. It is a new instance of
+ *          MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it
+ *          is no more needed.
+ *  \throw If \a mesh1 == NULL or \a mesh2 == NULL.
+ *  \throw If the meshes do not share the node coordinates array.
+ *  \throw If \a mesh1->getMeshDimension() < 0 or \a mesh2->getMeshDimension() < 0.
+ *  \throw If \a mesh1->getMeshDimension() != \a mesh2->getMeshDimension().
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2)
 {
   std::vector<const MEDCouplingUMesh *> tmp(2);
   tmp[0]=mesh1; tmp[1]=mesh2;
@@ -8448,88 +6772,6 @@ void MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector<ME
     } 
 }
 
-/*!
- * This method takes in input a cell defined by its MEDcouplingUMesh connectivity [ \a connBg , \a connEnd ) and returns its extruded cell by inserting the result at the end of ret.
- * \param nbOfNodesPerLev in parameter that specifies the number of nodes of one slice of global dataset
- * \param isQuad specifies the policy of connectivity.
- * @ret in/out parameter in which the result will be append
- */
-void MEDCouplingUMesh::AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector<int>& ret)
-{
-  INTERP_KERNEL::NormalizedCellType flatType=(INTERP_KERNEL::NormalizedCellType)connBg[0];
-  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(flatType);
-  ret.push_back(cm.getExtrudedType());
-  int deltaz=isQuad?2*nbOfNodesPerLev:nbOfNodesPerLev;
-  switch(flatType)
-  {
-    case INTERP_KERNEL::NORM_POINT1:
-      {
-        ret.push_back(connBg[1]);
-        ret.push_back(connBg[1]+nbOfNodesPerLev);
-        break;
-      }
-    case INTERP_KERNEL::NORM_SEG2:
-      {
-        int conn[4]={connBg[1],connBg[2],connBg[2]+deltaz,connBg[1]+deltaz};
-        ret.insert(ret.end(),conn,conn+4);
-        break;
-      }
-    case INTERP_KERNEL::NORM_SEG3:
-      {
-        int conn[8]={connBg[1],connBg[3],connBg[3]+deltaz,connBg[1]+deltaz,connBg[2],connBg[3]+nbOfNodesPerLev,connBg[2]+deltaz,connBg[1]+nbOfNodesPerLev};
-        ret.insert(ret.end(),conn,conn+8);
-        break;
-      }
-    case INTERP_KERNEL::NORM_QUAD4:
-      {
-        int conn[8]={connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz};
-        ret.insert(ret.end(),conn,conn+8);
-        break;
-      }
-    case INTERP_KERNEL::NORM_TRI3:
-      {
-        int conn[6]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz};
-        ret.insert(ret.end(),conn,conn+6);
-        break;
-      }
-    case INTERP_KERNEL::NORM_TRI6:
-      {
-        int conn[15]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4],connBg[5],connBg[6],connBg[4]+deltaz,connBg[5]+deltaz,connBg[6]+deltaz,
-          connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev};
-        ret.insert(ret.end(),conn,conn+15);
-        break;
-      }
-    case INTERP_KERNEL::NORM_QUAD8:
-      {
-        int conn[20]={
-          connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz,
-          connBg[5],connBg[6],connBg[7],connBg[8],connBg[5]+deltaz,connBg[6]+deltaz,connBg[7]+deltaz,connBg[8]+deltaz,
-          connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev,connBg[4]+nbOfNodesPerLev
-        };
-        ret.insert(ret.end(),conn,conn+20);
-        break;
-      }
-    case INTERP_KERNEL::NORM_POLYGON:
-      {
-        std::back_insert_iterator< std::vector<int> > ii(ret);
-        std::copy(connBg+1,connEnd,ii);
-        *ii++=-1;
-        std::reverse_iterator<const int *> rConnBg(connEnd);
-        std::reverse_iterator<const int *> rConnEnd(connBg+1);
-        std::transform(rConnBg,rConnEnd,ii,std::bind2nd(std::plus<int>(),deltaz));
-        std::size_t nbOfRadFaces=std::distance(connBg+1,connEnd);
-        for(std::size_t i=0;i<nbOfRadFaces;i++)
-          {
-            *ii++=-1;
-            int conn[4]={connBg[(i+1)%nbOfRadFaces+1],connBg[i+1],connBg[i+1]+deltaz,connBg[(i+1)%nbOfRadFaces+1]+deltaz};
-            std::copy(conn,conn+4,ii);
-          }
-        break;
-      }
-    default:
-      throw INTERP_KERNEL::Exception("A flat type has been detected that has not its extruded representation !");
-  }
-}
 
 /*!
  * This static operates only for coords in 3D. The polygon is specfied by its connectivity nodes in [ \a begin , \a end ).
@@ -8871,97 +7113,6 @@ void MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, c
     }
 }
 
-DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshLinear(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const
-{
-  int nbOfNodesExpected(skin->getNumberOfNodes());
-  const int *n2oPtr(n2o->begin());
-  MCAuto<DataArrayInt> revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New());
-  skin->getReverseNodalConnectivity(revNodal,revNodalI);
-  const int *revNodalPtr(revNodal->begin()),*revNodalIPtr(revNodalI->begin());
-  const int *nodalPtr(skin->getNodalConnectivity()->begin());
-  const int *nodalIPtr(skin->getNodalConnectivityIndex()->begin());
-  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1);
-  int *work(ret->getPointer());  *work++=INTERP_KERNEL::NORM_POLYGON;
-  if(nbOfNodesExpected<1)
-    return ret.retn();
-  int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]);
-  *work++=n2oPtr[prevNode];
-  for(int i=1;i<nbOfNodesExpected;i++)
-    {
-      if(nodalIPtr[prevCell+1]-nodalIPtr[prevCell]==3)
-        {
-          std::set<int> conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3);
-          conn.erase(prevNode);
-          if(conn.size()==1)
-            {
-              int curNode(*(conn.begin()));
-              *work++=n2oPtr[curNode];
-              std::set<int> shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]);
-              shar.erase(prevCell);
-              if(shar.size()==1)
-                {
-                  prevCell=*(shar.begin());
-                  prevNode=curNode;
-                }
-              else
-                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 2 !");
-            }
-          else
-            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 1 !");
-        }
-      else
-        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected cell !");
-    }
-  return ret.retn();
-}
-
-DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshQuadratic(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const
-{
-  int nbOfNodesExpected(skin->getNumberOfNodes());
-  int nbOfTurn(nbOfNodesExpected/2);
-  const int *n2oPtr(n2o->begin());
-  MCAuto<DataArrayInt> revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New());
-  skin->getReverseNodalConnectivity(revNodal,revNodalI);
-  const int *revNodalPtr(revNodal->begin()),*revNodalIPtr(revNodalI->begin());
-  const int *nodalPtr(skin->getNodalConnectivity()->begin());
-  const int *nodalIPtr(skin->getNodalConnectivityIndex()->begin());
-  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1);
-  int *work(ret->getPointer());  *work++=INTERP_KERNEL::NORM_QPOLYG;
-  if(nbOfNodesExpected<1)
-    return ret.retn();
-  int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]);
-  *work=n2oPtr[prevNode]; work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[0]+3]]; work++;
-  for(int i=1;i<nbOfTurn;i++)
-    {
-      if(nodalIPtr[prevCell+1]-nodalIPtr[prevCell]==4)
-        {
-          std::set<int> conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3);
-          conn.erase(prevNode);
-          if(conn.size()==1)
-            {
-              int curNode(*(conn.begin()));
-              *work=n2oPtr[curNode];
-              std::set<int> shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]);
-              shar.erase(prevCell);
-              if(shar.size()==1)
-                {
-                  int curCell(*(shar.begin()));
-                  work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[curCell]+3]];
-                  prevCell=curCell;
-                  prevNode=curNode;
-                  work++;
-                }
-              else
-                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 2 !");
-            }
-          else
-            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 1 !");
-        }
-      else
-        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected cell !");
-    }
-  return ret.retn();
-}
 
 /*!
  * This method makes the assumption spacedimension == meshdimension == 2.
@@ -9090,27 +7241,6 @@ MEDCouplingSkyLineArray *MEDCouplingUMesh::generateGraph() const
   return array;
 }
 
-/*!
- * This method put in zip format into parameter 'zipFrmt' in full interlace mode.
- * This format is often asked by INTERP_KERNEL algorithms to avoid many indirections into coordinates array.
- */
-void MEDCouplingUMesh::FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt)
-{
-  double *w=zipFrmt;
-  if(spaceDim==3)
-    for(int i=0;i<nbOfNodesInCell;i++)
-      w=std::copy(coo+3*conn[i],coo+3*conn[i]+3,w);
-  else if(spaceDim==2)
-    {
-      for(int i=0;i<nbOfNodesInCell;i++)
-        {
-          w=std::copy(coo+2*conn[i],coo+2*conn[i]+2,w);
-          *w++=0.;
-        }
-    }
-  else
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::FillInCompact3DMode : Invalid spaceDim specified : must be 2 or 3 !");
-}
 
 void MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
 {
@@ -9190,1863 +7320,161 @@ void MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData
   ofs << "  </" << getVTKDataSetType() << ">\n";
 }
 
-void MEDCouplingUMesh::reprQuickOverview(std::ostream& stream) const
-{
-  stream << "MEDCouplingUMesh C++ instance at " << this << ". Name : \"" << getName() << "\".";
-  if(_mesh_dim==-2)
-    { stream << " Not set !"; return ; }
-  stream << " Mesh dimension : " << _mesh_dim << ".";
-  if(_mesh_dim==-1)
-    return ;
-  if(!_coords)
-    { stream << " No coordinates set !"; return ; }
-  if(!_coords->isAllocated())
-    { stream << " Coordinates set but not allocated !"; return ; }
-  stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
-  stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
-  if(!_nodal_connec_index)
-    { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
-  if(!_nodal_connec_index->isAllocated())
-    { stream << std::endl << "Nodal connectivity set but not allocated !"; return ; }
-  int lgth=_nodal_connec_index->getNumberOfTuples();
-  int cpt=_nodal_connec_index->getNumberOfComponents();
-  if(cpt!=1 || lgth<1)
-    return ;
-  stream << std::endl << "Number of cells : " << lgth-1 << ".";
-}
-
-std::string MEDCouplingUMesh::getVTKDataSetType() const
-{
-  return std::string("UnstructuredGrid");
-}
-
-std::string MEDCouplingUMesh::getVTKFileExtension() const
-{
-  return std::string("vtu");
-}
-
-/*!
- * Partitions the first given 2D mesh using the second given 2D mesh as a tool, and
- * returns a result mesh constituted by polygons.
- * Thus the final result contains all nodes from m1 plus new nodes. However it doesn't necessarily contains
- * all nodes from m2.
- * The meshes should be in 2D space. In
- * addition, returns two arrays mapping cells of the result mesh to cells of the input
- * meshes.
- *  \param [in] m1 - the first input mesh which is a partitioned object. The mesh must be so that each point in the space covered by \a m1
- *                      must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes)
- *  \param [in] m2 - the second input mesh which is a partition tool. The mesh must be so that each point in the space covered by \a m2
- *                      must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes)
- *  \param [in] eps - precision used to detect coincident mesh entities.
- *  \param [out] cellNb1 - a new instance of DataArrayInt holding for each result
- *         cell an id of the cell of \a m1 it comes from. The caller is to delete
- *         this array using decrRef() as it is no more needed.
- *  \param [out] cellNb2 - a new instance of DataArrayInt holding for each result
- *         cell an id of the cell of \a m2 it comes from. -1 value means that a
- *         result cell comes from a cell (or part of cell) of \a m1 not overlapped by
- *         any cell of \a m2. The caller is to delete this array using decrRef() as
- *         it is no more needed.  
- *  \return MEDCouplingUMesh * - the result 2D mesh which is a new instance of
- *         MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it
- *         is no more needed.  
- *  \throw If the coordinates array is not set in any of the meshes.
- *  \throw If the nodal connectivity of cells is not defined in any of the meshes.
- *  \throw If any of the meshes is not a 2D mesh in 2D space.
- *
- *  \sa conformize2D, mergeNodes
- */
-MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2,
-                                                      double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2)
-{
-  if(!m1 || !m2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshes : input meshes must be not NULL !");
-  m1->checkFullyDefined();
-  m2->checkFullyDefined();
-  if(m1->getMeshDimension()!=2 || m1->getSpaceDimension()!=2 || m2->getMeshDimension()!=2 || m2->getSpaceDimension()!=2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshes works on umeshes m1 AND m2  with meshdim equal to 2 and spaceDim equal to 2 too!");
-
-  // Step 1: compute all edge intersections (new nodes)
-  std::vector< std::vector<int> > intersectEdge1, colinear2, subDiv2;
-  MEDCouplingUMesh *m1Desc=0,*m2Desc=0; // descending connec. meshes
-  DataArrayInt *desc1=0,*descIndx1=0,*revDesc1=0,*revDescIndx1=0,*desc2=0,*descIndx2=0,*revDesc2=0,*revDescIndx2=0;
-  std::vector<double> addCoo,addCoordsQuadratic;  // coordinates of newly created nodes
-  IntersectDescending2DMeshes(m1,m2,eps,intersectEdge1,colinear2, subDiv2,
-                              m1Desc,desc1,descIndx1,revDesc1,revDescIndx1,
-                              addCoo, m2Desc,desc2,descIndx2,revDesc2,revDescIndx2);
-  revDesc1->decrRef(); revDescIndx1->decrRef(); revDesc2->decrRef(); revDescIndx2->decrRef();
-  MCAuto<DataArrayInt> dd1(desc1),dd2(descIndx1),dd3(desc2),dd4(descIndx2);
-  MCAuto<MEDCouplingUMesh> dd5(m1Desc),dd6(m2Desc);
-
-  // Step 2: re-order newly created nodes according to the ordering found in m2
-  std::vector< std::vector<int> > intersectEdge2;
-  BuildIntersectEdges(m1Desc,m2Desc,addCoo,subDiv2,intersectEdge2);
-  subDiv2.clear(); dd5=0; dd6=0;
-
-  // Step 3:
-  std::vector<int> cr,crI; //no DataArrayInt because interface with Geometric2D
-  std::vector<int> cNb1,cNb2; //no DataArrayInt because interface with Geometric2D
-  BuildIntersecting2DCellsFromEdges(eps,m1,desc1->begin(),descIndx1->begin(),intersectEdge1,colinear2,m2,desc2->begin(),descIndx2->begin(),intersectEdge2,addCoo,
-                                    /* outputs -> */addCoordsQuadratic,cr,crI,cNb1,cNb2);
-
-  // Step 4: Prepare final result:
-  MCAuto<DataArrayDouble> addCooDa(DataArrayDouble::New());
-  addCooDa->alloc((int)(addCoo.size())/2,2);
-  std::copy(addCoo.begin(),addCoo.end(),addCooDa->getPointer());
-  MCAuto<DataArrayDouble> addCoordsQuadraticDa(DataArrayDouble::New());
-  addCoordsQuadraticDa->alloc((int)(addCoordsQuadratic.size())/2,2);
-  std::copy(addCoordsQuadratic.begin(),addCoordsQuadratic.end(),addCoordsQuadraticDa->getPointer());
-  std::vector<const DataArrayDouble *> coordss(4);
-  coordss[0]=m1->getCoords(); coordss[1]=m2->getCoords(); coordss[2]=addCooDa; coordss[3]=addCoordsQuadraticDa;
-  MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coordss));
-  MCAuto<MEDCouplingUMesh> ret(MEDCouplingUMesh::New("Intersect2D",2));
-  MCAuto<DataArrayInt> conn(DataArrayInt::New()); conn->alloc((int)cr.size(),1); std::copy(cr.begin(),cr.end(),conn->getPointer());
-  MCAuto<DataArrayInt> connI(DataArrayInt::New()); connI->alloc((int)crI.size(),1); std::copy(crI.begin(),crI.end(),connI->getPointer());
-  MCAuto<DataArrayInt> c1(DataArrayInt::New()); c1->alloc((int)cNb1.size(),1); std::copy(cNb1.begin(),cNb1.end(),c1->getPointer());
-  MCAuto<DataArrayInt> c2(DataArrayInt::New()); c2->alloc((int)cNb2.size(),1); std::copy(cNb2.begin(),cNb2.end(),c2->getPointer());
-  ret->setConnectivity(conn,connI,true);
-  ret->setCoords(coo);
-  cellNb1=c1.retn(); cellNb2=c2.retn();
-  return ret.retn();
-}
-
-/// @cond INTERNAL
-
-bool IsColinearOfACellOf(const std::vector< std::vector<int> >& intersectEdge1, const std::vector<int>& candidates, int start, int stop, int& retVal)
-{
-  if(candidates.empty())
-    return false;
-  for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
-    {
-      const std::vector<int>& pool(intersectEdge1[*it]);
-      int tmp[2]; tmp[0]=start; tmp[1]=stop;
-      if(std::search(pool.begin(),pool.end(),tmp,tmp+2)!=pool.end())
-        {
-          retVal=*it+1;
-          return true;
-        }
-      tmp[0]=stop; tmp[1]=start;
-      if(std::search(pool.begin(),pool.end(),tmp,tmp+2)!=pool.end())
-        {
-          retVal=-*it-1;
-          return true;
-        }
-    }
-  return false;
-}
-
-MEDCouplingUMesh *BuildMesh1DCutFrom(const MEDCouplingUMesh *mesh1D, const std::vector< std::vector<int> >& intersectEdge2, const DataArrayDouble *coords1, const std::vector<double>& addCoo, const std::map<int,int>& mergedNodes, const std::vector< std::vector<int> >& colinear2, const std::vector< std::vector<int> >& intersectEdge1,
-                                     MCAuto<DataArrayInt>& idsInRetColinear, MCAuto<DataArrayInt>& idsInMesh1DForIdsInRetColinear)
-{
-  idsInRetColinear=DataArrayInt::New(); idsInRetColinear->alloc(0,1);
-  idsInMesh1DForIdsInRetColinear=DataArrayInt::New(); idsInMesh1DForIdsInRetColinear->alloc(0,1);
-  int nCells(mesh1D->getNumberOfCells());
-  if(nCells!=(int)intersectEdge2.size())
-    throw INTERP_KERNEL::Exception("BuildMesh1DCutFrom : internal error # 1 !");
-  const DataArrayDouble *coo2(mesh1D->getCoords());
-  const int *c(mesh1D->getNodalConnectivity()->begin()),*ci(mesh1D->getNodalConnectivityIndex()->begin());
-  const double *coo2Ptr(coo2->begin());
-  int offset1(coords1->getNumberOfTuples());
-  int offset2(offset1+coo2->getNumberOfTuples());
-  int offset3(offset2+addCoo.size()/2);
-  std::vector<double> addCooQuad;
-  MCAuto<DataArrayInt> cOut(DataArrayInt::New()),ciOut(DataArrayInt::New()); cOut->alloc(0,1); ciOut->alloc(1,1); ciOut->setIJ(0,0,0);
-  int tmp[4],cicnt(0),kk(0);
-  for(int i=0;i<nCells;i++)
-    {
-      std::map<MCAuto<INTERP_KERNEL::Node>,int> m;
-      INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coo2Ptr,m));
-      const std::vector<int>& subEdges(intersectEdge2[i]);
-      int nbSubEdge(subEdges.size()/2);
-      for(int j=0;j<nbSubEdge;j++,kk++)
-        {
-          MCAuto<INTERP_KERNEL::Node> n1(MEDCouplingUMeshBuildQPNode(subEdges[2*j],coords1->begin(),offset1,coo2Ptr,offset2,addCoo)),n2(MEDCouplingUMeshBuildQPNode(subEdges[2*j+1],coords1->begin(),offset1,coo2Ptr,offset2,addCoo));
-          MCAuto<INTERP_KERNEL::Edge> e2(e->buildEdgeLyingOnMe(n1,n2));
-          INTERP_KERNEL::Edge *e2Ptr(e2);
-          std::map<int,int>::const_iterator itm;
-          if(dynamic_cast<INTERP_KERNEL::EdgeArcCircle *>(e2Ptr))
-            {
-              tmp[0]=INTERP_KERNEL::NORM_SEG3;
-              itm=mergedNodes.find(subEdges[2*j]);
-              tmp[1]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j];
-              itm=mergedNodes.find(subEdges[2*j+1]);
-              tmp[2]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j+1];
-              tmp[3]=offset3+(int)addCooQuad.size()/2;
-              double tmp2[2];
-              e2->getBarycenter(tmp2); addCooQuad.insert(addCooQuad.end(),tmp2,tmp2+2);
-              cicnt+=4;
-              cOut->insertAtTheEnd(tmp,tmp+4);
-              ciOut->pushBackSilent(cicnt);
-            }
-          else
-            {
-              tmp[0]=INTERP_KERNEL::NORM_SEG2;
-              itm=mergedNodes.find(subEdges[2*j]);
-              tmp[1]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j];
-              itm=mergedNodes.find(subEdges[2*j+1]);
-              tmp[2]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j+1];
-              cicnt+=3;
-              cOut->insertAtTheEnd(tmp,tmp+3);
-              ciOut->pushBackSilent(cicnt);
-            }
-          int tmp00;
-          if(IsColinearOfACellOf(intersectEdge1,colinear2[i],tmp[1],tmp[2],tmp00))
-            {
-              idsInRetColinear->pushBackSilent(kk);
-              idsInMesh1DForIdsInRetColinear->pushBackSilent(tmp00);
-            }
-        }
-      e->decrRef();
-    }
-  MCAuto<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(mesh1D->getName(),1));
-  ret->setConnectivity(cOut,ciOut,true);
-  MCAuto<DataArrayDouble> arr3(DataArrayDouble::New());
-  arr3->useArray(&addCoo[0],false,C_DEALLOC,(int)addCoo.size()/2,2);
-  MCAuto<DataArrayDouble> arr4(DataArrayDouble::New()); arr4->useArray(&addCooQuad[0],false,C_DEALLOC,(int)addCooQuad.size()/2,2);
-  std::vector<const DataArrayDouble *> coordss(4);
-  coordss[0]=coords1; coordss[1]=mesh1D->getCoords(); coordss[2]=arr3; coordss[3]=arr4;
-  MCAuto<DataArrayDouble> arr(DataArrayDouble::Aggregate(coordss));
-  ret->setCoords(arr);
-  return ret.retn();
-}
-
-MEDCouplingUMesh *BuildRefined2DCellLinear(const DataArrayDouble *coords, const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1)
-{
-  std::vector<int> allEdges;
-  for(const int *it2(descBg);it2!=descEnd;it2++)
-    {
-      const std::vector<int>& edge1(intersectEdge1[std::abs(*it2)-1]);
-      if(*it2>0)
-        allEdges.insert(allEdges.end(),edge1.begin(),edge1.end());
-      else
-        allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend());
-    }
-  std::size_t nb(allEdges.size());
-  if(nb%2!=0)
-    throw INTERP_KERNEL::Exception("BuildRefined2DCellLinear : internal error 1 !");
-  std::size_t nbOfEdgesOf2DCellSplit(nb/2);
-  MCAuto<MEDCouplingUMesh> ret(MEDCouplingUMesh::New("",2));
-  ret->setCoords(coords);
-  ret->allocateCells(1);
-  std::vector<int> connOut(nbOfEdgesOf2DCellSplit);
-  for(std::size_t kk=0;kk<nbOfEdgesOf2DCellSplit;kk++)
-    connOut[kk]=allEdges[2*kk];
-  ret->insertNextCell(INTERP_KERNEL::NORM_POLYGON,connOut.size(),&connOut[0]);
-  return ret.retn();
-}
-
-MEDCouplingUMesh *BuildRefined2DCellQuadratic(const DataArrayDouble *coords, const MEDCouplingUMesh *mesh2D, int cellIdInMesh2D, const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1)
-{
-  const int *c(mesh2D->getNodalConnectivity()->begin()),*ci(mesh2D->getNodalConnectivityIndex()->begin());
-  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[cellIdInMesh2D]]));
-  std::size_t ii(0);
-  unsigned sz(cm.getNumberOfSons2(c+ci[cellIdInMesh2D]+1,ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]-1));
-  if(sz!=std::distance(descBg,descEnd))
-    throw INTERP_KERNEL::Exception("BuildRefined2DCellQuadratic : internal error 1 !");
-  INTERP_KERNEL::AutoPtr<int> tmpPtr(new int[ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]]);
-  std::vector<int> allEdges,centers;
-  const double *coordsPtr(coords->begin());
-  MCAuto<DataArrayDouble> addCoo(DataArrayDouble::New()); addCoo->alloc(0,1);
-  int offset(coords->getNumberOfTuples());
-  for(const int *it2(descBg);it2!=descEnd;it2++,ii++)
-    {
-      INTERP_KERNEL::NormalizedCellType typeOfSon;
-      cm.fillSonCellNodalConnectivity2(ii,c+ci[cellIdInMesh2D]+1,ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]-1,tmpPtr,typeOfSon);
-      const std::vector<int>& edge1(intersectEdge1[std::abs(*it2)-1]);
-      if(*it2>0)
-        allEdges.insert(allEdges.end(),edge1.begin(),edge1.end());
-      else
-        allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend());
-      if(edge1.size()==2)
-        centers.push_back(tmpPtr[2]);//special case where no subsplit of edge -> reuse the original center.
-      else
-        {//the current edge has been subsplit -> create corresponding centers.
-          std::size_t nbOfCentersToAppend(edge1.size()/2);
-          std::map< MCAuto<INTERP_KERNEL::Node>,int> m;
-          MCAuto<INTERP_KERNEL::Edge> ee(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpPtr,coordsPtr,m));
-          std::vector<int>::const_iterator it3(allEdges.end()-edge1.size());
-          for(std::size_t k=0;k<nbOfCentersToAppend;k++)
-            {
-              double tmpp[2];
-              const double *aa(coordsPtr+2*(*it3++));
-              const double *bb(coordsPtr+2*(*it3++));
-              ee->getMiddleOfPoints(aa,bb,tmpp);
-              addCoo->insertAtTheEnd(tmpp,tmpp+2);
-              centers.push_back(offset+k);
-            }
-        }
-    }
-  std::size_t nb(allEdges.size());
-  if(nb%2!=0)
-    throw INTERP_KERNEL::Exception("BuildRefined2DCellQuadratic : internal error 2 !");
-  std::size_t nbOfEdgesOf2DCellSplit(nb/2);
-  MCAuto<MEDCouplingUMesh> ret(MEDCouplingUMesh::New("",2));
-  if(addCoo->empty())
-    ret->setCoords(coords);
-  else
-    {
-      addCoo->rearrange(2);
-      addCoo=DataArrayDouble::Aggregate(coords,addCoo);
-      ret->setCoords(addCoo);
-    }
-  ret->allocateCells(1);
-  std::vector<int> connOut(nbOfEdgesOf2DCellSplit);
-  for(std::size_t kk=0;kk<nbOfEdgesOf2DCellSplit;kk++)
-    connOut[kk]=allEdges[2*kk];
-  connOut.insert(connOut.end(),centers.begin(),centers.end());
-  ret->insertNextCell(INTERP_KERNEL::NORM_QPOLYG,connOut.size(),&connOut[0]);
-  return ret.retn();
-}
-
-/*!
- * This method creates a refinement of a cell in \a mesh2D. Those cell is defined by descending connectivity and the sorted subdivided nodal connectivity
- * of those edges.
- *
- * \param [in] mesh2D - The origin 2D mesh. \b Warning \b coords are not those of \a mesh2D. But mesh2D->getCoords()==coords[:mesh2D->getNumberOfNodes()]
- */
-MEDCouplingUMesh *BuildRefined2DCell(const DataArrayDouble *coords, const MEDCouplingUMesh *mesh2D, int cellIdInMesh2D, const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1)
-{
-  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(mesh2D->getTypeOfCell(cellIdInMesh2D)));
-  if(!cm.isQuadratic())
-    return BuildRefined2DCellLinear(coords,descBg,descEnd,intersectEdge1);
-  else
-    return BuildRefined2DCellQuadratic(coords,mesh2D,cellIdInMesh2D,descBg,descEnd,intersectEdge1);
-}
-
-void AddCellInMesh2D(MEDCouplingUMesh *mesh2D, const std::vector<int>& conn, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& edges)
-{
-  bool isQuad(false);
-  for(std::vector< MCAuto<INTERP_KERNEL::Edge> >::const_iterator it=edges.begin();it!=edges.end();it++)
-    {
-      const INTERP_KERNEL::Edge *ee(*it);
-      if(dynamic_cast<const INTERP_KERNEL::EdgeArcCircle *>(ee))
-        isQuad=true;
-    }
-  if(!isQuad)
-    mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,conn.size(),&conn[0]);
-  else
-    {
-      const double *coo(mesh2D->getCoords()->begin());
-      std::size_t sz(conn.size());
-      std::vector<double> addCoo;
-      std::vector<int> conn2(conn);
-      int offset(mesh2D->getNumberOfNodes());
-      for(std::size_t i=0;i<sz;i++)
-        {
-          double tmp[2];
-          edges[(i+1)%sz]->getMiddleOfPoints(coo+2*conn[i],coo+2*conn[(i+1)%sz],tmp);// tony a chier i+1 -> i
-          addCoo.insert(addCoo.end(),tmp,tmp+2);
-          conn2.push_back(offset+(int)i);
-        }
-      mesh2D->getCoords()->rearrange(1);
-      mesh2D->getCoords()->pushBackValsSilent(&addCoo[0],&addCoo[0]+addCoo.size());
-      mesh2D->getCoords()->rearrange(2);
-      mesh2D->insertNextCell(INTERP_KERNEL::NORM_QPOLYG,conn2.size(),&conn2[0]);
-    }
-}
-
-/*!
- * \b WARNING edges in out1 coming from \a splitMesh1D are \b NOT oriented because only used for equation of curve.
- *
- * This method cuts in 2 parts the input 2D cell given using boundaries description (\a edge1Bis and \a edge1BisPtr) using
- * a set of edges defined in \a splitMesh1D.
- */
-void BuildMesh2DCutInternal2(const MEDCouplingUMesh *splitMesh1D, const std::vector<int>& edge1Bis, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& edge1BisPtr,
-                             std::vector< std::vector<int> >& out0, std::vector< std::vector< MCAuto<INTERP_KERNEL::Edge> > >& out1)
-{
-  std::size_t nb(edge1Bis.size()/2);
-  std::size_t nbOfEdgesOf2DCellSplit(nb/2);
-  int iEnd(splitMesh1D->getNumberOfCells());
-  if(iEnd==0)
-    throw INTERP_KERNEL::Exception("BuildMesh2DCutInternal2 : internal error ! input 1D mesh must have at least one cell !");
-  std::size_t ii,jj;
-  const int *cSplitPtr(splitMesh1D->getNodalConnectivity()->begin()),*ciSplitPtr(splitMesh1D->getNodalConnectivityIndex()->begin());
-  for(ii=0;ii<nb && edge1Bis[2*ii]!=cSplitPtr[ciSplitPtr[0]+1];ii++);
-  for(jj=ii;jj<nb && edge1Bis[2*jj+1]!=cSplitPtr[ciSplitPtr[iEnd-1]+2];jj++);
-  //
-  if(jj==nb)
-    {//the edges splitMesh1D[iStart:iEnd] does not fully cut the current 2D cell -> single output cell
-      out0.resize(1); out1.resize(1);
-      std::vector<int>& connOut(out0[0]);
-      connOut.resize(nbOfEdgesOf2DCellSplit);
-      std::vector< MCAuto<INTERP_KERNEL::Edge> >& edgesPtr(out1[0]);
-      edgesPtr.resize(nbOfEdgesOf2DCellSplit);
-      for(std::size_t kk=0;kk<nbOfEdgesOf2DCellSplit;kk++)
-        {
-          connOut[kk]=edge1Bis[2*kk];
-          edgesPtr[kk]=edge1BisPtr[2*kk];
-        }
-    }
-  else
-    {
-      // [i,iEnd[ contains the
-      out0.resize(2); out1.resize(2);
-      std::vector<int>& connOutLeft(out0[0]);
-      std::vector<int>& connOutRight(out0[1]);//connOutLeft should end with edge1Bis[2*ii] and connOutRight should end with edge1Bis[2*jj+1]
-      std::vector< MCAuto<INTERP_KERNEL::Edge> >& eleft(out1[0]);
-      std::vector< MCAuto<INTERP_KERNEL::Edge> >& eright(out1[1]);
-      for(std::size_t k=ii;k<jj+1;k++)
-        { connOutLeft.push_back(edge1Bis[2*k+1]); eleft.push_back(edge1BisPtr[2*k+1]); }
-      std::vector< MCAuto<INTERP_KERNEL::Edge> > ees(iEnd);
-      for(int ik=0;ik<iEnd;ik++)
-        {
-          std::map< MCAuto<INTERP_KERNEL::Node>,int> m;
-          MCAuto<INTERP_KERNEL::Edge> ee(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)cSplitPtr[ciSplitPtr[ik]],cSplitPtr+ciSplitPtr[ik]+1,splitMesh1D->getCoords()->begin(),m));
-          ees[ik]=ee;
-        }
-      for(int ik=iEnd-1;ik>=0;ik--)
-        connOutLeft.push_back(cSplitPtr[ciSplitPtr[ik]+1]);
-      for(std::size_t k=jj+1;k<nbOfEdgesOf2DCellSplit+ii;k++)
-        { connOutRight.push_back(edge1Bis[2*k+1]); eright.push_back(edge1BisPtr[2*k+1]); }
-      eleft.insert(eleft.end(),ees.rbegin(),ees.rend());
-      for(int ik=0;ik<iEnd;ik++)
-        connOutRight.push_back(cSplitPtr[ciSplitPtr[ik]+2]);
-      eright.insert(eright.end(),ees.begin(),ees.end());
-    }
-}
-
-/// @endcond
-
-/// @cond INTERNAL
-
-struct CellInfo
-{
-public:
-  CellInfo() { }
-  CellInfo(const std::vector<int>& edges, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& edgesPtr);
-public:
-  std::vector<int> _edges;
-  std::vector< MCAuto<INTERP_KERNEL::Edge> > _edges_ptr;
-};
-
-CellInfo::CellInfo(const std::vector<int>& edges, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& edgesPtr)
-{
-  std::size_t nbe(edges.size());
-  std::vector<int> edges2(2*nbe); std::vector< MCAuto<INTERP_KERNEL::Edge> > edgesPtr2(2*nbe);
-  for(std::size_t i=0;i<nbe;i++)
-    {
-      edges2[2*i]=edges[i]; edges2[2*i+1]=edges[(i+1)%nbe];
-      edgesPtr2[2*i]=edgesPtr[(i+1)%nbe]; edgesPtr2[2*i+1]=edgesPtr[(i+1)%nbe];//tony a chier
-    }
-  _edges.resize(4*nbe); _edges_ptr.resize(4*nbe);
-  std::copy(edges2.begin(),edges2.end(),_edges.begin()); std::copy(edges2.begin(),edges2.end(),_edges.begin()+2*nbe);
-  std::copy(edgesPtr2.begin(),edgesPtr2.end(),_edges_ptr.begin()); std::copy(edgesPtr2.begin(),edgesPtr2.end(),_edges_ptr.begin()+2*nbe);
-}
-
-class EdgeInfo
-{
-public:
-  EdgeInfo(int istart, int iend, const MCAuto<MEDCouplingUMesh>& mesh):_istart(istart),_iend(iend),_mesh(mesh),_left(-7),_right(-7) { }
-  EdgeInfo(int istart, int iend, int pos, const MCAuto<INTERP_KERNEL::Edge>& edge):_istart(istart),_iend(iend),_edge(edge),_left(pos),_right(pos+1) { }
-  bool isInMyRange(int pos) const { return pos>=_istart && pos<_iend; }
-  void somethingHappendAt(int pos, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newRight);
-  void feedEdgeInfoAt(double eps, const MEDCouplingUMesh *mesh2D, int offset, int neighbors[2]) const;
-private:
-  int _istart;
-  int _iend;
-  MCAuto<MEDCouplingUMesh> _mesh;
-  MCAuto<INTERP_KERNEL::Edge> _edge;
-  int _left;
-  int _right;
-};
-
-void EdgeInfo::somethingHappendAt(int pos, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newRight)
-{
-  const MEDCouplingUMesh *mesh(_mesh);
-  if(mesh)
-    return ;
-  if(_right<pos)
-    return ;
-  if(_left>pos)
-    { _left++; _right++; return ; }
-  if(_right==pos)
-    {
-      bool isLeft(std::find(newLeft.begin(),newLeft.end(),_edge)!=newLeft.end()),isRight(std::find(newRight.begin(),newRight.end(),_edge)!=newRight.end());
-      if((isLeft && isRight) || (!isLeft && !isRight))
-        throw INTERP_KERNEL::Exception("EdgeInfo::somethingHappendAt : internal error # 1 !");
-      if(isLeft)
-        return ;
-      if(isRight)
-        {
-          _right++;
-          return ;
-        }
-    }
-  if(_left==pos)
-    {
-      bool isLeft(std::find(newLeft.begin(),newLeft.end(),_edge)!=newLeft.end()),isRight(std::find(newRight.begin(),newRight.end(),_edge)!=newRight.end());
-      if((isLeft && isRight) || (!isLeft && !isRight))
-        throw INTERP_KERNEL::Exception("EdgeInfo::somethingHappendAt : internal error # 2 !");
-      if(isLeft)
-        {
-          _right++;
-          return ;
-        }
-      if(isRight)
-        {
-          _left++;
-          _right++;
-          return ;
-        }
-    }
-}
-
-void EdgeInfo::feedEdgeInfoAt(double eps, const MEDCouplingUMesh *mesh2D, int offset, int neighbors[2]) const
-{
-  const MEDCouplingUMesh *mesh(_mesh);
-  if(!mesh)
-    {
-      neighbors[0]=offset+_left; neighbors[1]=offset+_right;
-    }
-  else
-    {// not fully splitting cell case
-      if(mesh2D->getNumberOfCells()==1)
-        {//little optimization. 1 cell no need to find in which cell mesh is !
-          neighbors[0]=offset; neighbors[1]=offset;
-          return;
-        }
-      else
-        {
-          MCAuto<DataArrayDouble> barys(mesh->computeCellCenterOfMass());
-          int cellId(mesh2D->getCellContainingPoint(barys->begin(),eps));
-          if(cellId==-1)
-            throw INTERP_KERNEL::Exception("EdgeInfo::feedEdgeInfoAt : internal error !");
-          neighbors[0]=offset+cellId; neighbors[1]=offset+cellId;
-        }
-    }
-}
-
-class VectorOfCellInfo
-{
-public:
-  VectorOfCellInfo(const std::vector<int>& edges, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& edgesPtr);
-  std::size_t size() const { return _pool.size(); }
-  int getPositionOf(double eps, const MEDCouplingUMesh *mesh) const;
-  void setMeshAt(int pos, const MCAuto<MEDCouplingUMesh>& mesh, int istart, int iend, const MCAuto<MEDCouplingUMesh>& mesh1DInCase, const std::vector< std::vector<int> >& edges, const std::vector< std::vector< MCAuto<INTERP_KERNEL::Edge> > >& edgePtrs);
-  const std::vector<int>& getConnOf(int pos) const { return get(pos)._edges; }
-  const std::vector< MCAuto<INTERP_KERNEL::Edge> >& getEdgePtrOf(int pos) const { return get(pos)._edges_ptr; }
-  MCAuto<MEDCouplingUMesh> getZeMesh() const { return _ze_mesh; }
-  void feedEdgeInfoAt(double eps, int pos, int offset, int neighbors[2]) const;
-private:
-  int getZePosOfEdgeGivenItsGlobalId(int pos) const;
-  void updateEdgeInfo(int pos, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newRight);
-  const CellInfo& get(int pos) const;
-  CellInfo& get(int pos);
-private:
-  std::vector<CellInfo> _pool;
-  MCAuto<MEDCouplingUMesh> _ze_mesh;
-  std::vector<EdgeInfo> _edge_info;
-};
-
-VectorOfCellInfo::VectorOfCellInfo(const std::vector<int>& edges, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& edgesPtr):_pool(1)
-{
-  _pool[0]._edges=edges;
-  _pool[0]._edges_ptr=edgesPtr;
-}
-
-int VectorOfCellInfo::getPositionOf(double eps, const MEDCouplingUMesh *mesh) const
-{
-  if(_pool.empty())
-    throw INTERP_KERNEL::Exception("VectorOfCellSplitter::getPositionOf : empty !");
-  if(_pool.size()==1)
-    return 0;
-  const MEDCouplingUMesh *zeMesh(_ze_mesh);
-  if(!zeMesh)
-    throw INTERP_KERNEL::Exception("VectorOfCellSplitter::getPositionOf : null aggregated mesh !");
-  MCAuto<DataArrayDouble> barys(mesh->computeCellCenterOfMass());
-  return zeMesh->getCellContainingPoint(barys->begin(),eps);
-}
-
-void VectorOfCellInfo::setMeshAt(int pos, const MCAuto<MEDCouplingUMesh>& mesh, int istart, int iend, const MCAuto<MEDCouplingUMesh>& mesh1DInCase, const std::vector< std::vector<int> >& edges, const std::vector< std::vector< MCAuto<INTERP_KERNEL::Edge> > >& edgePtrs)
-{
-  get(pos);//to check pos
-  bool isFast(pos==0 && _pool.size()==1);
-  std::size_t sz(edges.size());
-  // dealing with edges
-  if(sz==1)
-    _edge_info.push_back(EdgeInfo(istart,iend,mesh1DInCase));
-  else
-    _edge_info.push_back(EdgeInfo(istart,iend,pos,edgePtrs[0].back()));
-  //
-  std::vector<CellInfo> pool(_pool.size()-1+sz);
-  for(int i=0;i<pos;i++)
-    pool[i]=_pool[i];
-  for(std::size_t j=0;j<sz;j++)
-    pool[pos+j]=CellInfo(edges[j],edgePtrs[j]);
-  for(int i=pos+1;i<(int)_pool.size();i++)
-    pool[i+sz-1]=_pool[i];
-  _pool=pool;
-  //
-  if(sz==2)
-    updateEdgeInfo(pos,edgePtrs[0],edgePtrs[1]);
-  //
-  if(isFast)
-    {
-      _ze_mesh=mesh;
-      return ;
-    }
-  //
-  std::vector< MCAuto<MEDCouplingUMesh> > ms;
-  if(pos>0)
-    {
-      MCAuto<MEDCouplingUMesh> elt(static_cast<MEDCouplingUMesh *>(_ze_mesh->buildPartOfMySelfSlice(0,pos,true)));
-      ms.push_back(elt);
-    }
-  ms.push_back(mesh);
-  if(pos<_ze_mesh->getNumberOfCells()-1)
-  {
-    MCAuto<MEDCouplingUMesh> elt(static_cast<MEDCouplingUMesh *>(_ze_mesh->buildPartOfMySelfSlice(pos+1,_ze_mesh->getNumberOfCells(),true)));
-    ms.push_back(elt);
-  }
-  std::vector< const MEDCouplingUMesh *> ms2(ms.size());
-  for(std::size_t j=0;j<ms2.size();j++)
-    ms2[j]=ms[j];
-  _ze_mesh=MEDCouplingUMesh::MergeUMeshesOnSameCoords(ms2);
-}
-
-void VectorOfCellInfo::feedEdgeInfoAt(double eps, int pos, int offset, int neighbors[2]) const
-{
-  _edge_info[getZePosOfEdgeGivenItsGlobalId(pos)].feedEdgeInfoAt(eps,_ze_mesh,offset,neighbors);
-}
-
-int VectorOfCellInfo::getZePosOfEdgeGivenItsGlobalId(int pos) const
-{
-  if(pos<0)
-    throw INTERP_KERNEL::Exception("VectorOfCellInfo::getZePosOfEdgeGivenItsGlobalId : invalid id ! Must be >=0 !");
-  int ret(0);
-  for(std::vector<EdgeInfo>::const_iterator it=_edge_info.begin();it!=_edge_info.end();it++,ret++)
-    {
-      if((*it).isInMyRange(pos))
-        return ret;
-    }
-  throw INTERP_KERNEL::Exception("VectorOfCellInfo::getZePosOfEdgeGivenItsGlobalId : invalid id !");
-}
-
-void VectorOfCellInfo::updateEdgeInfo(int pos, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newRight)
-{
-  get(pos);//to check;
-  if(_edge_info.empty())
-    return ;
-  std::size_t sz(_edge_info.size()-1);
-  for(std::size_t i=0;i<sz;i++)
-    _edge_info[i].somethingHappendAt(pos,newLeft,newRight);
-}
-
-const CellInfo& VectorOfCellInfo::get(int pos) const
-{
-  if(pos<0 || pos>=(int)_pool.size())
-    throw INTERP_KERNEL::Exception("VectorOfCellSplitter::get const : invalid pos !");
-  return _pool[pos];
-}
-
-CellInfo& VectorOfCellInfo::get(int pos)
-{
-  if(pos<0 || pos>=(int)_pool.size())
-    throw INTERP_KERNEL::Exception("VectorOfCellSplitter::get : invalid pos !");
-  return _pool[pos];
-}
-
-/*!
- * Given :
- * - a \b closed set of edges ( \a allEdges and \a allEdgesPtr ) that defines the split descending 2D cell.
- * - \a splitMesh1D a split 2D curve mesh contained into 2D cell defined above.
- *
- * This method returns the 2D mesh and feeds \a idsLeftRight using offset.
- *
- * Algorithm : \a splitMesh1D is cut into contiguous parts. Each contiguous parts will build incrementally the output 2D cells.
- *
- * \param [in] allEdges a list of pairs (beginNode, endNode). Linked with \a allEdgesPtr to get the equation of edge.
- */
-MEDCouplingUMesh *BuildMesh2DCutInternal(double eps, const MEDCouplingUMesh *splitMesh1D, const std::vector<int>& allEdges, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& allEdgesPtr, int offset,
-                                         MCAuto<DataArrayInt>& idsLeftRight)
-{
-  int nbCellsInSplitMesh1D(splitMesh1D->getNumberOfCells());
-  if(nbCellsInSplitMesh1D==0)
-    throw INTERP_KERNEL::Exception("BuildMesh2DCutInternal : internal error ! input 1D mesh must have at least one cell !");
-  const int *cSplitPtr(splitMesh1D->getNodalConnectivity()->begin()),*ciSplitPtr(splitMesh1D->getNodalConnectivityIndex()->begin());
-  std::size_t nb(allEdges.size()),jj;
-  if(nb%2!=0)
-    throw INTERP_KERNEL::Exception("BuildMesh2DCutFrom : internal error 2 !");
-  std::vector<int> edge1Bis(nb*2);
-  std::vector< MCAuto<INTERP_KERNEL::Edge> > edge1BisPtr(nb*2);
-  std::copy(allEdges.begin(),allEdges.end(),edge1Bis.begin());
-  std::copy(allEdges.begin(),allEdges.end(),edge1Bis.begin()+nb);
-  std::copy(allEdgesPtr.begin(),allEdgesPtr.end(),edge1BisPtr.begin());
-  std::copy(allEdgesPtr.begin(),allEdgesPtr.end(),edge1BisPtr.begin()+nb);
-  //
-  idsLeftRight=DataArrayInt::New(); idsLeftRight->alloc(nbCellsInSplitMesh1D*2); idsLeftRight->fillWithValue(-2); idsLeftRight->rearrange(2);
-  int *idsLeftRightPtr(idsLeftRight->getPointer());
-  VectorOfCellInfo pool(edge1Bis,edge1BisPtr);
-  for(int iStart=0;iStart<nbCellsInSplitMesh1D;)
-    {// split [0:nbCellsInSplitMesh1D) in contiguous parts [iStart:iEnd)
-      int iEnd(iStart);
-      for(;iEnd<nbCellsInSplitMesh1D;)
-        {
-          for(jj=0;jj<nb && edge1Bis[2*jj+1]!=cSplitPtr[ciSplitPtr[iEnd]+2];jj++);
-          if(jj!=nb)
-            break;
-          else
-            iEnd++;
-        }
-      if(iEnd<nbCellsInSplitMesh1D)
-        iEnd++;
-      //
-      MCAuto<MEDCouplingUMesh> partOfSplitMesh1D(static_cast<MEDCouplingUMesh *>(splitMesh1D->buildPartOfMySelfSlice(iStart,iEnd,1,true)));
-      int pos(pool.getPositionOf(eps,partOfSplitMesh1D));
-      //
-      MCAuto<MEDCouplingUMesh>retTmp(MEDCouplingUMesh::New("",2));
-      retTmp->setCoords(splitMesh1D->getCoords());
-      retTmp->allocateCells();
-
-      std::vector< std::vector<int> > out0;
-      std::vector< std::vector< MCAuto<INTERP_KERNEL::Edge> > > out1;
-
-      BuildMesh2DCutInternal2(partOfSplitMesh1D,pool.getConnOf(pos),pool.getEdgePtrOf(pos),out0,out1);
-      for(std::size_t cnt=0;cnt<out0.size();cnt++)
-        AddCellInMesh2D(retTmp,out0[cnt],out1[cnt]);
-      pool.setMeshAt(pos,retTmp,iStart,iEnd,partOfSplitMesh1D,out0,out1);
-      //
-      iStart=iEnd;
-    }
-  for(int mm=0;mm<nbCellsInSplitMesh1D;mm++)
-    pool.feedEdgeInfoAt(eps,mm,offset,idsLeftRightPtr+2*mm);
-  return pool.getZeMesh().retn();
-}
-
-MEDCouplingUMesh *BuildMesh2DCutFrom(double eps, int cellIdInMesh2D, const MEDCouplingUMesh *mesh2DDesc, const MEDCouplingUMesh *splitMesh1D,
-                                     const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1, int offset,
-                                     MCAuto<DataArrayInt>& idsLeftRight)
-{
-  const int *cdescPtr(mesh2DDesc->getNodalConnectivity()->begin()),*cidescPtr(mesh2DDesc->getNodalConnectivityIndex()->begin());
-  //
-  std::vector<int> allEdges;
-  std::vector< MCAuto<INTERP_KERNEL::Edge> > allEdgesPtr; // for each sub edge in splitMesh2D the uncut Edge object of the original mesh2D
-  for(const int *it(descBg);it!=descEnd;it++) // for all edges in the descending connectivity of the 2D mesh in relative Fortran mode
-    {
-      int edgeId(std::abs(*it)-1);
-      std::map< MCAuto<INTERP_KERNEL::Node>,int> m;
-      MCAuto<INTERP_KERNEL::Edge> ee(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)cdescPtr[cidescPtr[edgeId]],cdescPtr+cidescPtr[edgeId]+1,mesh2DDesc->getCoords()->begin(),m));
-      const std::vector<int>& edge1(intersectEdge1[edgeId]);
-      if(*it>0)
-        allEdges.insert(allEdges.end(),edge1.begin(),edge1.end());
-      else
-        allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend());
-      std::size_t sz(edge1.size());
-      for(std::size_t cnt=0;cnt<sz;cnt++)
-        allEdgesPtr.push_back(ee);
-    }
-  //
-  return BuildMesh2DCutInternal(eps,splitMesh1D,allEdges,allEdgesPtr,offset,idsLeftRight);
-}
-
-bool AreEdgeEqual(const double *coo2D, const INTERP_KERNEL::CellModel& typ1, const int *conn1, const INTERP_KERNEL::CellModel& typ2, const int *conn2, double eps)
-{
-  if(!typ1.isQuadratic() && !typ2.isQuadratic())
-    {//easy case comparison not
-      return conn1[0]==conn2[0] && conn1[1]==conn2[1];
-    }
-  else if(typ1.isQuadratic() && typ2.isQuadratic())
-    {
-      bool status0(conn1[0]==conn2[0] && conn1[1]==conn2[1]);
-      if(!status0)
-        return false;
-      if(conn1[2]==conn2[2])
-        return true;
-      const double *a(coo2D+2*conn1[2]),*b(coo2D+2*conn2[2]);
-      double dist(sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])));
-      return dist<eps;
-    }
-  else
-    {//only one is quadratic
-      bool status0(conn1[0]==conn2[0] && conn1[1]==conn2[1]);
-      if(!status0)
-        return false;
-      const double *a(0),*bb(0),*be(0);
-      if(typ1.isQuadratic())
-        {
-          a=coo2D+2*conn1[2]; bb=coo2D+2*conn2[0]; be=coo2D+2*conn2[1];
-        }
-      else
-        {
-          a=coo2D+2*conn2[2]; bb=coo2D+2*conn1[0]; be=coo2D+2*conn1[1];
-        }
-      double b[2]; b[0]=(be[0]+bb[0])/2.; b[1]=(be[1]+bb[1])/2.;
-      double dist(sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])));
-      return dist<eps;
-    }
-}
-
-/*!
- * This method returns among the cellIds [ \a candidatesIn2DBg , \a candidatesIn2DEnd ) in \a mesh2DSplit those exactly sharing \a cellIdInMesh1DSplitRelative in \a mesh1DSplit.
- * \a mesh2DSplit and \a mesh1DSplit are expected to share the coordinates array.
- *
- * \param [in] cellIdInMesh1DSplitRelative is in Fortran mode using sign to specify direction.
- */
-int FindRightCandidateAmong(const MEDCouplingUMesh *mesh2DSplit, const int *candidatesIn2DBg, const int *candidatesIn2DEnd, const MEDCouplingUMesh *mesh1DSplit, int cellIdInMesh1DSplitRelative, double eps)
-{
-  if(candidatesIn2DEnd==candidatesIn2DBg)
-    throw INTERP_KERNEL::Exception("FindRightCandidateAmong : internal error 1 !");
-  const double *coo(mesh2DSplit->getCoords()->begin());
-  if(std::distance(candidatesIn2DBg,candidatesIn2DEnd)==1)
-    return *candidatesIn2DBg;
-  int edgeId(std::abs(cellIdInMesh1DSplitRelative)-1);
-  MCAuto<MEDCouplingUMesh> cur1D(static_cast<MEDCouplingUMesh *>(mesh1DSplit->buildPartOfMySelf(&edgeId,&edgeId+1,true)));
-  if(cellIdInMesh1DSplitRelative<0)
-    cur1D->changeOrientationOfCells();
-  const int *c1D(cur1D->getNodalConnectivity()->begin());
-  const INTERP_KERNEL::CellModel& ref1DType(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c1D[0]));
-  for(const int *it=candidatesIn2DBg;it!=candidatesIn2DEnd;it++)
-    {
-      MCAuto<MEDCouplingUMesh> cur2D(static_cast<MEDCouplingUMesh *>(mesh2DSplit->buildPartOfMySelf(it,it+1,true)));
-      const int *c(cur2D->getNodalConnectivity()->begin()),*ci(cur2D->getNodalConnectivityIndex()->begin());
-      const INTERP_KERNEL::CellModel &cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[0]]));
-      unsigned sz(cm.getNumberOfSons2(c+ci[0]+1,ci[1]-ci[0]-1));
-      INTERP_KERNEL::AutoPtr<int> tmpPtr(new int[ci[1]-ci[0]]);
-      for(unsigned it2=0;it2<sz;it2++)
-        {
-          INTERP_KERNEL::NormalizedCellType typeOfSon;
-          cm.fillSonCellNodalConnectivity2(it2,c+ci[0]+1,ci[1]-ci[0]-1,tmpPtr,typeOfSon);
-          const INTERP_KERNEL::CellModel &curCM(INTERP_KERNEL::CellModel::GetCellModel(typeOfSon));
-          if(AreEdgeEqual(coo,ref1DType,c1D+1,curCM,tmpPtr,eps))
-            return *it;
-        }
-    }
-  throw INTERP_KERNEL::Exception("FindRightCandidateAmong : internal error 2 ! Unable to find the edge among split cell !");
-}
-
-/// @endcond
-
-/*!
- * Partitions the first given 2D mesh using the second given 1D mesh as a tool.
- * Thus the final result contains the aggregation of nodes of \a mesh2D, then nodes of \a mesh1D, then new nodes that are the result of the intersection
- * and finaly, in case of quadratic polygon the centers of edges new nodes.
- * The meshes should be in 2D space. In addition, returns two arrays mapping cells of the resulting mesh to cells of the input.
- *
- * \param [in] mesh2D - the 2D mesh (spacedim=meshdim=2) to be intersected using \a mesh1D tool. The mesh must be so that each point in the space covered by \a mesh2D
- *                      must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes)
- * \param [in] mesh1D - the 1D mesh (spacedim=2 meshdim=1) the is the tool that will be used to intersect \a mesh2D. \a mesh1D must be ordered consecutively. If it is not the case
- *                      you can invoke orderConsecutiveCells1D on \a mesh1D.
- * \param [in] eps - precision used to perform intersections and localization operations.
- * \param [out] splitMesh2D - the result of the split of \a mesh2D mesh.
- * \param [out] splitMesh1D - the result of the split of \a mesh1D mesh.
- * \param [out] cellIdInMesh2D - the array that gives for each cell id \a i in \a splitMesh2D the id in \a mesh2D it comes from.
- *                               So this array has a number of tuples equal to the number of cells of \a splitMesh2D and a number of component equal to 1.
- * \param [out] cellIdInMesh1D - the array of pair that gives for each cell id \a i in \a splitMesh1D the cell in \a splitMesh2D on the left for the 1st component
- *                               and the cell in \a splitMesh2D on the right for the 2nt component. -1 means no cell.
- *                               So this array has a number of tuples equal to the number of cells of \a splitMesh1D and a number of components equal to 2.
- *
- * \sa Intersect2DMeshes, orderConsecutiveCells1D, conformize2D, mergeNodes
- */
-void MEDCouplingUMesh::Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D, const MEDCouplingUMesh *mesh1D, double eps, MEDCouplingUMesh *&splitMesh2D, MEDCouplingUMesh *&splitMesh1D, DataArrayInt *&cellIdInMesh2D, DataArrayInt *&cellIdInMesh1D)
-{
-  if(!mesh2D || !mesh1D)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshWith1DLine : input meshes must be not NULL !");
-  mesh2D->checkFullyDefined();
-  mesh1D->checkFullyDefined();
-  const std::vector<std::string>& compNames(mesh2D->getCoords()->getInfoOnComponents());
-  if(mesh2D->getMeshDimension()!=2 || mesh2D->getSpaceDimension()!=2 || mesh1D->getMeshDimension()!=1 || mesh1D->getSpaceDimension()!=2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshWith1DLine works with mesh2D with spacedim=meshdim=2 and mesh1D with meshdim=1 spaceDim=2 !");
-  // Step 1: compute all edge intersections (new nodes)
-  std::vector< std::vector<int> > intersectEdge1, colinear2, subDiv2;
-  std::vector<double> addCoo,addCoordsQuadratic;  // coordinates of newly created nodes
-  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
-  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
-  //
-  // Build desc connectivity
-  DataArrayInt *desc1(DataArrayInt::New()),*descIndx1(DataArrayInt::New()),*revDesc1(DataArrayInt::New()),*revDescIndx1(DataArrayInt::New());
-  MCAuto<DataArrayInt> dd1(desc1),dd2(descIndx1),dd3(revDesc1),dd4(revDescIndx1);
-  MCAuto<MEDCouplingUMesh> m1Desc(mesh2D->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1));
-  std::map<int,int> mergedNodes;
-  Intersect1DMeshes(m1Desc,mesh1D,eps,intersectEdge1,colinear2,subDiv2,addCoo,mergedNodes);
-  // use mergeNodes to fix intersectEdge1
-  for(std::vector< std::vector<int> >::iterator it0=intersectEdge1.begin();it0!=intersectEdge1.end();it0++)
-    {
-      std::size_t n((*it0).size()/2);
-      int eltStart((*it0)[0]),eltEnd((*it0)[2*n-1]);
-      std::map<int,int>::const_iterator it1;
-      it1=mergedNodes.find(eltStart);
-      if(it1!=mergedNodes.end())
-        (*it0)[0]=(*it1).second;
-      it1=mergedNodes.find(eltEnd);
-      if(it1!=mergedNodes.end())
-        (*it0)[2*n-1]=(*it1).second;
-    }
-  //
-  MCAuto<DataArrayDouble> addCooDa(DataArrayDouble::New());
-  addCooDa->useArray(&addCoo[0],false,C_DEALLOC,(int)addCoo.size()/2,2);
-  // Step 2: re-order newly created nodes according to the ordering found in m2
-  std::vector< std::vector<int> > intersectEdge2;
-  BuildIntersectEdges(m1Desc,mesh1D,addCoo,subDiv2,intersectEdge2);
-  subDiv2.clear();
-  // Step 3: compute splitMesh1D
-  MCAuto<DataArrayInt> idsInRet1Colinear,idsInDescMesh2DForIdsInRetColinear;
-  MCAuto<DataArrayInt> ret2(DataArrayInt::New()); ret2->alloc(0,1);
-  MCAuto<MEDCouplingUMesh> ret1(BuildMesh1DCutFrom(mesh1D,intersectEdge2,mesh2D->getCoords(),addCoo,mergedNodes,colinear2,intersectEdge1,
-      idsInRet1Colinear,idsInDescMesh2DForIdsInRetColinear));
-  MCAuto<DataArrayInt> ret3(DataArrayInt::New()); ret3->alloc(ret1->getNumberOfCells()*2,1); ret3->fillWithValue(std::numeric_limits<int>::max()); ret3->rearrange(2);
-  MCAuto<DataArrayInt> idsInRet1NotColinear(idsInRet1Colinear->buildComplement(ret1->getNumberOfCells()));
-  // deal with cells in mesh2D that are not cut but only some of their edges are
-  MCAuto<DataArrayInt> idsInDesc2DToBeRefined(idsInDescMesh2DForIdsInRetColinear->deepCopy());
-  idsInDesc2DToBeRefined->abs(); idsInDesc2DToBeRefined->applyLin(1,-1);
-  idsInDesc2DToBeRefined=idsInDesc2DToBeRefined->buildUnique();
-  MCAuto<DataArrayInt> out0s;//ids in mesh2D that are impacted by the fact that some edges of \a mesh1D are part of the edges of those cells
-  if(!idsInDesc2DToBeRefined->empty())
-    {
-      DataArrayInt *out0(0),*outi0(0);
-      MEDCouplingUMesh::ExtractFromIndexedArrays(idsInDesc2DToBeRefined->begin(),idsInDesc2DToBeRefined->end(),dd3,dd4,out0,outi0);
-      MCAuto<DataArrayInt> outi0s(outi0);
-      out0s=out0;
-      out0s=out0s->buildUnique();
-      out0s->sort(true);
-    }
-  //
-  MCAuto<MEDCouplingUMesh> ret1NonCol(static_cast<MEDCouplingUMesh *>(ret1->buildPartOfMySelf(idsInRet1NotColinear->begin(),idsInRet1NotColinear->end())));
-  MCAuto<DataArrayDouble> baryRet1(ret1NonCol->computeCellCenterOfMass());
-  MCAuto<DataArrayInt> elts,eltsIndex;
-  mesh2D->getCellsContainingPoints(baryRet1->begin(),baryRet1->getNumberOfTuples(),eps,elts,eltsIndex);
-  MCAuto<DataArrayInt> eltsIndex2(eltsIndex->deltaShiftIndex());
-  MCAuto<DataArrayInt> eltsIndex3(eltsIndex2->findIdsEqual(1));
-  if(eltsIndex2->count(0)+eltsIndex3->getNumberOfTuples()!=ret1NonCol->getNumberOfCells())
-    throw INTERP_KERNEL::Exception("Intersect2DMeshWith1DLine : internal error 1 !");
-  MCAuto<DataArrayInt> cellsToBeModified(elts->buildUnique());
-  MCAuto<DataArrayInt> untouchedCells(cellsToBeModified->buildComplement(mesh2D->getNumberOfCells()));
-  if((DataArrayInt *)out0s)
-    untouchedCells=untouchedCells->buildSubstraction(out0s);//if some edges in ret1 are colinear to descending mesh of mesh2D remove cells from untouched one
-  std::vector< MCAuto<MEDCouplingUMesh> > outMesh2DSplit;
-  // OK all is ready to insert in ret2 mesh
-  if(!untouchedCells->empty())
-    {// the most easy part, cells in mesh2D not impacted at all
-      outMesh2DSplit.push_back(static_cast<MEDCouplingUMesh *>(mesh2D->buildPartOfMySelf(untouchedCells->begin(),untouchedCells->end())));
-      outMesh2DSplit.back()->setCoords(ret1->getCoords());
-      ret2->pushBackValsSilent(untouchedCells->begin(),untouchedCells->end());
-    }
-  if((DataArrayInt *)out0s)
-    {// here dealing with cells in out0s but not in cellsToBeModified
-      MCAuto<DataArrayInt> fewModifiedCells(out0s->buildSubstraction(cellsToBeModified));
-      const int *rdptr(dd3->begin()),*rdiptr(dd4->begin()),*dptr(dd1->begin()),*diptr(dd2->begin());
-      for(const int *it=fewModifiedCells->begin();it!=fewModifiedCells->end();it++)
-        {
-          outMesh2DSplit.push_back(BuildRefined2DCell(ret1->getCoords(),mesh2D,*it,dptr+diptr[*it],dptr+diptr[*it+1],intersectEdge1));
-          ret1->setCoords(outMesh2DSplit.back()->getCoords());
-        }
-      int offset(ret2->getNumberOfTuples());
-      ret2->pushBackValsSilent(fewModifiedCells->begin(),fewModifiedCells->end());
-      MCAuto<DataArrayInt> partOfRet3(DataArrayInt::New()); partOfRet3->alloc(2*idsInRet1Colinear->getNumberOfTuples(),1);
-      partOfRet3->fillWithValue(std::numeric_limits<int>::max()); partOfRet3->rearrange(2);
-      int kk(0),*ret3ptr(partOfRet3->getPointer());
-      for(const int *it=idsInDescMesh2DForIdsInRetColinear->begin();it!=idsInDescMesh2DForIdsInRetColinear->end();it++,kk++)
-        {
-          int faceId(std::abs(*it)-1);
-          for(const int *it2=rdptr+rdiptr[faceId];it2!=rdptr+rdiptr[faceId+1];it2++)
-            {
-              int tmp(fewModifiedCells->findIdFirstEqual(*it2));
-              if(tmp!=-1)
-                {
-                  if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],-(*it))!=dptr+diptr[*it2+1])
-                    ret3ptr[2*kk]=tmp+offset;
-                  if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],(*it))!=dptr+diptr[*it2+1])
-                    ret3ptr[2*kk+1]=tmp+offset;
-                }
-              else
-                {//the current edge is shared by a 2D cell that will be split just after
-                  if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],-(*it))!=dptr+diptr[*it2+1])
-                    ret3ptr[2*kk]=-(*it2+1);
-                  if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],(*it))!=dptr+diptr[*it2+1])
-                    ret3ptr[2*kk+1]=-(*it2+1);
-                }
-            }
-        }
-      m1Desc->setCoords(ret1->getCoords());
-      ret1NonCol->setCoords(ret1->getCoords());
-      ret3->setPartOfValues3(partOfRet3,idsInRet1Colinear->begin(),idsInRet1Colinear->end(),0,2,1,true);
-      if(!outMesh2DSplit.empty())
-        {
-          DataArrayDouble *da(outMesh2DSplit.back()->getCoords());
-          for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator itt=outMesh2DSplit.begin();itt!=outMesh2DSplit.end();itt++)
-            (*itt)->setCoords(da);
-        }
-    }
-  cellsToBeModified=cellsToBeModified->buildUniqueNotSorted();
-  for(const int *it=cellsToBeModified->begin();it!=cellsToBeModified->end();it++)
-    {
-      MCAuto<DataArrayInt> idsNonColPerCell(elts->findIdsEqual(*it));
-      idsNonColPerCell->transformWithIndArr(eltsIndex3->begin(),eltsIndex3->end());
-      MCAuto<DataArrayInt> idsNonColPerCell2(idsInRet1NotColinear->selectByTupleId(idsNonColPerCell->begin(),idsNonColPerCell->end()));
-      MCAuto<MEDCouplingUMesh> partOfMesh1CuttingCur2DCell(static_cast<MEDCouplingUMesh *>(ret1NonCol->buildPartOfMySelf(idsNonColPerCell->begin(),idsNonColPerCell->end())));
-      MCAuto<DataArrayInt> partOfRet3;
-      MCAuto<MEDCouplingUMesh> splitOfOneCell(BuildMesh2DCutFrom(eps,*it,m1Desc,partOfMesh1CuttingCur2DCell,dd1->begin()+dd2->getIJ(*it,0),dd1->begin()+dd2->getIJ((*it)+1,0),intersectEdge1,ret2->getNumberOfTuples(),partOfRet3));
-      ret3->setPartOfValues3(partOfRet3,idsNonColPerCell2->begin(),idsNonColPerCell2->end(),0,2,1,true);
-      outMesh2DSplit.push_back(splitOfOneCell);
-      for(int i=0;i<splitOfOneCell->getNumberOfCells();i++)
-        ret2->pushBackSilent(*it);
-    }
-  //
-  std::size_t nbOfMeshes(outMesh2DSplit.size());
-  std::vector<const MEDCouplingUMesh *> tmp(nbOfMeshes);
-  for(std::size_t i=0;i<nbOfMeshes;i++)
-    tmp[i]=outMesh2DSplit[i];
-  //
-  ret1->getCoords()->setInfoOnComponents(compNames);
-  MCAuto<MEDCouplingUMesh> ret2D(MEDCouplingUMesh::MergeUMeshesOnSameCoords(tmp));
-  // To finish - filter ret3 - std::numeric_limits<int>::max() -> -1 - negate values must be resolved.
-  ret3->rearrange(1);
-  MCAuto<DataArrayInt> edgesToDealWith(ret3->findIdsStricltyNegative());
-  for(const int *it=edgesToDealWith->begin();it!=edgesToDealWith->end();it++)
-    {
-      int old2DCellId(-ret3->getIJ(*it,0)-1);
-      MCAuto<DataArrayInt> candidates(ret2->findIdsEqual(old2DCellId));
-      ret3->setIJ(*it,0,FindRightCandidateAmong(ret2D,candidates->begin(),candidates->end(),ret1,*it%2==0?-((*it)/2+1):(*it)/2+1,eps));// div by 2 because 2 components natively in ret3
-    }
-  ret3->changeValue(std::numeric_limits<int>::max(),-1);
-  ret3->rearrange(2);
-  //
-  splitMesh1D=ret1.retn();
-  splitMesh2D=ret2D.retn();
-  cellIdInMesh2D=ret2.retn();
-  cellIdInMesh1D=ret3.retn();
-}
-
-/**
- * Private. Third step of the partitioning algorithm (Intersect2DMeshes): reconstruct full 2D cells from the
- * (newly created) nodes corresponding to the edge intersections.
- * Output params:
- * @param[out] cr, crI connectivity of the resulting mesh
- * @param[out] cNb1, cNb2 correspondance arrays giving for the merged mesh the initial cells IDs in m1 / m2
- * TODO: describe input parameters
- */
-void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const int *desc1, const int *descIndx1,
-                                                         const std::vector<std::vector<int> >& intesctEdges1, const std::vector< std::vector<int> >& colinear2,
-                                                         const MEDCouplingUMesh *m2, const int *desc2, const int *descIndx2, const std::vector<std::vector<int> >& intesctEdges2,
-                                                         const std::vector<double>& addCoords,
-                                                         std::vector<double>& addCoordsQuadratic, std::vector<int>& cr, std::vector<int>& crI, std::vector<int>& cNb1, std::vector<int>& cNb2)
-{
-  static const int SPACEDIM=2;
-  const double *coo1(m1->getCoords()->begin());
-  const int *conn1(m1->getNodalConnectivity()->begin()),*connI1(m1->getNodalConnectivityIndex()->begin());
-  int offset1(m1->getNumberOfNodes());
-  const double *coo2(m2->getCoords()->begin());
-  const int *conn2(m2->getNodalConnectivity()->begin()),*connI2(m2->getNodalConnectivityIndex()->begin());
-  int offset2(offset1+m2->getNumberOfNodes());
-  int offset3(offset2+((int)addCoords.size())/2);
-  MCAuto<DataArrayDouble> bbox1Arr(m1->getBoundingBoxForBBTree()),bbox2Arr(m2->getBoundingBoxForBBTree());
-  const double *bbox1(bbox1Arr->begin()),*bbox2(bbox2Arr->begin());
-  // Here a BBTree on 2D-cells, not on segments:
-  BBTree<SPACEDIM,int> myTree(bbox2,0,0,m2->getNumberOfCells(),eps);
-  int ncell1(m1->getNumberOfCells());
-  crI.push_back(0);
-  for(int i=0;i<ncell1;i++)
-    {
-      std::vector<int> candidates2;
-      myTree.getIntersectingElems(bbox1+i*2*SPACEDIM,candidates2);
-      std::map<INTERP_KERNEL::Node *,int> mapp;
-      std::map<int,INTERP_KERNEL::Node *> mappRev;
-      INTERP_KERNEL::QuadraticPolygon pol1;
-      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)conn1[connI1[i]];
-      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
-      // Populate mapp and mappRev with nodes from the current cell (i) from mesh1 - this also builds the Node* objects:
-      MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,/* output */mapp,mappRev);
-      // pol1 is the full cell from mesh2, in QP format, with all the additional intersecting nodes.
-      pol1.buildFromCrudeDataArray(mappRev,cm.isQuadratic(),conn1+connI1[i]+1,coo1,
-          desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1);
-      //
-      std::set<INTERP_KERNEL::Edge *> edges1;// store all edges of pol1 that are NOT consumed by intersect cells. If any after iteration over candidates2 -> a part of pol1 should appear in result
-      std::set<INTERP_KERNEL::Edge *> edgesBoundary2;// store all edges that are on boundary of (pol2 intersect pol1) minus edges on pol1.
-      INTERP_KERNEL::IteratorOnComposedEdge it1(&pol1);
-      for(it1.first();!it1.finished();it1.next())
-        edges1.insert(it1.current()->getPtr());
-      //
-      std::map<int,std::vector<INTERP_KERNEL::ElementaryEdge *> > edgesIn2ForShare; // common edges
-      std::vector<INTERP_KERNEL::QuadraticPolygon> pol2s(candidates2.size());
-      int ii=0;
-      for(std::vector<int>::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++)
-        {
-          INTERP_KERNEL::NormalizedCellType typ2=(INTERP_KERNEL::NormalizedCellType)conn2[connI2[*it2]];
-          const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel(typ2);
-          // Complete mapping with elements coming from the current cell it2 in mesh2:
-          MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,/* output */mapp,mappRev);
-          // pol2 is the new QP in the final merged result.
-          pol2s[ii].buildFromCrudeDataArray2(mappRev,cm2.isQuadratic(),conn2+connI2[*it2]+1,coo2,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,
-              pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2, /* output */ edgesIn2ForShare);
-        }
-      ii=0;
-      for(std::vector<int>::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++)
-        {
-          INTERP_KERNEL::ComposedEdge::InitLocationsWithOther(pol1,pol2s[ii]);
-          pol2s[ii].updateLocOfEdgeFromCrudeDataArray2(desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2);
-          //MEDCouplingUMeshAssignOnLoc(pol1,pol2,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,colinear2);
-          pol1.buildPartitionsAbs(pol2s[ii],edges1,edgesBoundary2,mapp,i,*it2,offset3,addCoordsQuadratic,cr,crI,cNb1,cNb2);
-        }
-      // Deals with remaining (non-consumed) edges from m1: these are the edges that were never touched
-      // by m2 but that we still want to keep in the final result.
-      if(!edges1.empty())
-        {
-          try
-          {
-              INTERP_KERNEL::QuadraticPolygon::ComputeResidual(pol1,edges1,edgesBoundary2,mapp,offset3,i,addCoordsQuadratic,cr,crI,cNb1,cNb2);
-          }
-          catch(INTERP_KERNEL::Exception& e)
-          {
-              std::ostringstream oss; oss << "Error when computing residual of cell #" << i << " in source/m1 mesh ! Maybe the neighbours of this cell in mesh are not well connected !\n" << "The deep reason is the following : " << e.what();
-              throw INTERP_KERNEL::Exception(oss.str());
-          }
-        }
-      for(std::map<int,INTERP_KERNEL::Node *>::const_iterator it=mappRev.begin();it!=mappRev.end();it++)
-        (*it).second->decrRef();
-    }
-}
-
-/**
- * Provides a renumbering of the cells of this (which has to be a piecewise connected 1D line), so that
- * the segments of the line are indexed in consecutive order (i.e. cells \a i and \a i+1 are neighbors).
- * This doesn't modify the mesh. This method only works using nodal connectivity consideration. Coordinates of nodes are ignored here.
- * The caller is to deal with the resulting DataArrayInt.
- *  \throw If the coordinate array is not set.
- *  \throw If the nodal connectivity of the cells is not defined.
- *  \throw If m1 is not a mesh of dimension 2, or m1 is not a mesh of dimension 1
- *  \throw If m2 is not a (piecewise) line (i.e. if a point has more than 2 adjacent segments)
- *
- * \sa DataArrayInt::sortEachPairToMakeALinkedList
- */
-DataArrayInt *MEDCouplingUMesh::orderConsecutiveCells1D() const
-{
-  checkFullyDefined();
-  if(getMeshDimension()!=1)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orderConsecutiveCells1D works on unstructured mesh with meshdim = 1 !");
-
-  // Check that this is a line (and not a more complex 1D mesh) - each point is used at most by 2 segments:
-  MCAuto<DataArrayInt> _d(DataArrayInt::New()),_dI(DataArrayInt::New());
-  MCAuto<DataArrayInt> _rD(DataArrayInt::New()),_rDI(DataArrayInt::New());
-  MCAuto<MEDCouplingUMesh> m_points(buildDescendingConnectivity(_d, _dI, _rD, _rDI));
-  const int *d(_d->begin()), *dI(_dI->begin());
-  const int *rD(_rD->begin()), *rDI(_rDI->begin());
-  MCAuto<DataArrayInt> _dsi(_rDI->deltaShiftIndex());
-  const int * dsi(_dsi->begin());
-  MCAuto<DataArrayInt> dsii = _dsi->findIdsNotInRange(0,3);
-  m_points=0;
-  if (dsii->getNumberOfTuples())
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orderConsecutiveCells1D only work with a mesh being a (piecewise) connected line!");
-
-  int nc(getNumberOfCells());
-  MCAuto<DataArrayInt> result(DataArrayInt::New());
-  result->alloc(nc,1);
-
-  // set of edges not used so far
-  std::set<int> edgeSet;
-  for (int i=0; i<nc; edgeSet.insert(i), i++);
-
-  int startSeg=0;
-  int newIdx=0;
-  // while we have points with only one neighbor segments
-  do
-    {
-      std::list<int> linePiece;
-      // fills a list of consecutive segment linked to startSeg. This can go forward or backward.
-      for (int direction=0;direction<2;direction++) // direction=0 --> forward, direction=1 --> backward
-        {
-          // Fill the list forward (resp. backward) from the start segment:
-          int activeSeg = startSeg;
-          int prevPointId = -20;
-          int ptId;
-          while (!edgeSet.empty())
-            {
-              if (!(direction == 1 && prevPointId==-20)) // prevent adding twice startSeg
-                {
-                  if (direction==0)
-                    linePiece.push_back(activeSeg);
-                  else
-                    linePiece.push_front(activeSeg);
-                  edgeSet.erase(activeSeg);
-                }
-
-              int ptId1 = d[dI[activeSeg]], ptId2 = d[dI[activeSeg]+1];
-              ptId = direction ? (ptId1 == prevPointId ? ptId2 : ptId1) : (ptId2 == prevPointId ? ptId1 : ptId2);
-              if (dsi[ptId] == 1) // hitting the end of the line
-                break;
-              prevPointId = ptId;
-              int seg1 = rD[rDI[ptId]], seg2 = rD[rDI[ptId]+1];
-              activeSeg = (seg1 == activeSeg) ? seg2 : seg1;
-            }
-        }
-      // Done, save final piece into DA:
-      std::copy(linePiece.begin(), linePiece.end(), result->getPointer()+newIdx);
-      newIdx += linePiece.size();
-
-      // identify next valid start segment (one which is not consumed)
-      if(!edgeSet.empty())
-        startSeg = *(edgeSet.begin());
-    }
-  while (!edgeSet.empty());
-  return result.retn();
-}
-
-/// @cond INTERNAL
-
-void IKGeo2DInternalMapper2(INTERP_KERNEL::Node *n, const std::map<MCAuto<INTERP_KERNEL::Node>,int>& m, int forbVal0, int forbVal1, std::vector<int>& isect)
-{
-  MCAuto<INTERP_KERNEL::Node> nTmp(n); nTmp->incrRef();
-  std::map<MCAuto<INTERP_KERNEL::Node>,int>::const_iterator it(m.find(nTmp));
-  if(it==m.end())
-    throw INTERP_KERNEL::Exception("Internal error in remapping !");
-  int v((*it).second);
-  if(v==forbVal0 || v==forbVal1)
-    return ;
-  if(std::find(isect.begin(),isect.end(),v)==isect.end())
-    isect.push_back(v);
-}
-
-bool IKGeo2DInternalMapper(const INTERP_KERNEL::ComposedEdge& c, const std::map<MCAuto<INTERP_KERNEL::Node>,int>& m, int forbVal0, int forbVal1, std::vector<int>& isect)
-{
-  int sz(c.size());
-  if(sz<=1)
-    return false;
-  bool presenceOfOn(false);
-  for(int i=0;i<sz;i++)
-    {
-      INTERP_KERNEL::ElementaryEdge *e(c[i]);
-      if(e->getLoc()!=INTERP_KERNEL::FULL_ON_1)
-        continue ;
-      IKGeo2DInternalMapper2(e->getStartNode(),m,forbVal0,forbVal1,isect);
-      IKGeo2DInternalMapper2(e->getEndNode(),m,forbVal0,forbVal1,isect);
-    }
-  return presenceOfOn;
-}
-
-/// @endcond
-
-/**
- * This method split some of edges of 2D cells in \a this. The edges to be split are specified in \a subNodesInSeg
- * and in \a subNodesInSegI using \ref numbering-indirect storage mode.
- * To do the work this method can optionally needs information about middle of subedges for quadratic cases if
- * a minimal creation of new nodes is wanted.
- * So this method try to reduce at most the number of new nodes. The only case that can lead this method to add
- * nodes if a SEG3 is split without information of middle.
- * \b WARNING : is returned value is different from 0 a call to MEDCouplingUMesh::mergeNodes is necessary to
- * avoid to have a non conform mesh.
- *
- * \return int - the number of new nodes created (in most of cases 0).
- * 
- * \throw If \a this is not coherent.
- * \throw If \a this has not spaceDim equal to 2.
- * \throw If \a this has not meshDim equal to 2.
- * \throw If some subcells needed to be split are orphan.
- * \sa MEDCouplingUMesh::conformize2D
- */
-int MEDCouplingUMesh::split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt, const DataArrayInt *midOptI)
-{
-  if(!desc || !descI || !subNodesInSeg || !subNodesInSegI)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : the 4 first arrays must be not null !");
-  desc->checkAllocated(); descI->checkAllocated(); subNodesInSeg->checkAllocated(); subNodesInSegI->checkAllocated();
-  if(getSpaceDimension()!=2 || getMeshDimension()!=2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : This method only works for meshes with spaceDim=2 and meshDim=2 !");
-  if(midOpt==0 && midOptI==0)
-    {
-      split2DCellsLinear(desc,descI,subNodesInSeg,subNodesInSegI);
-      return 0;
-    }
-  else if(midOpt!=0 && midOptI!=0)
-    return split2DCellsQuadratic(desc,descI,subNodesInSeg,subNodesInSegI,midOpt,midOptI);
-  else
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : middle parameters must be set to null for all or not null for all.");
-}
-
-/*!
- * \b WARNING this method is \b potentially \b non \b const (if returned array is empty).
- * \b WARNING this method lead to have a non geometric type sorted mesh (for MED file users) !
- * This method performs a conformization of \b this. So if a edge in \a this can be split into entire edges in \a this this method
- * will suppress such edges to use sub edges in \a this. So this method does not add nodes in \a this if merged edges are both linear (INTERP_KERNEL::NORM_SEG2).
- * In the other cases new nodes can be created. If any are created, they will be appended at the end of the coordinates object before the invokation of this method.
- * 
- * Whatever the returned value, this method does not alter the order of cells in \a this neither the orientation of cells.
- * The modified cells, if any, are systematically declared as NORM_POLYGON or NORM_QPOLYG depending on the initial quadraticness of geometric type.
- *
- * This method expects that \b this has a meshDim equal 2 and spaceDim equal to 2 too.
- * This method expects that all nodes in \a this are not closer than \a eps.
- * If it is not the case you can invoke MEDCouplingUMesh::mergeNodes before calling this method.
- * 
- * \param [in] eps the relative error to detect merged edges.
- * \return DataArrayInt  * - The list of cellIds in \a this that have been subdivided. If empty, nothing changed in \a this (as if it were a const method). The array is a newly allocated array
- *                           that the user is expected to deal with.
- *
- * \throw If \a this is not coherent.
- * \throw If \a this has not spaceDim equal to 2.
- * \throw If \a this has not meshDim equal to 2.
- * \sa MEDCouplingUMesh::mergeNodes, MEDCouplingUMesh::split2DCells
- */
-DataArrayInt *MEDCouplingUMesh::conformize2D(double eps)
-{
-  static const int SPACEDIM=2;
-  checkConsistencyLight();
-  if(getSpaceDimension()!=2 || getMeshDimension()!=2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : This method only works for meshes with spaceDim=2 and meshDim=2 !");
-  MCAuto<DataArrayInt> desc1(DataArrayInt::New()),descIndx1(DataArrayInt::New()),revDesc1(DataArrayInt::New()),revDescIndx1(DataArrayInt::New());
-  MCAuto<MEDCouplingUMesh> mDesc(buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1));
-  const int *c(mDesc->getNodalConnectivity()->begin()),*ci(mDesc->getNodalConnectivityIndex()->begin()),*rd(revDesc1->begin()),*rdi(revDescIndx1->begin());
-  MCAuto<DataArrayDouble> bboxArr(mDesc->getBoundingBoxForBBTree());
-  const double *bbox(bboxArr->begin()),*coords(getCoords()->begin());
-  int nCell(getNumberOfCells()),nDescCell(mDesc->getNumberOfCells());
-  std::vector< std::vector<int> > intersectEdge(nDescCell),overlapEdge(nDescCell);
-  std::vector<double> addCoo;
-  BBTree<SPACEDIM,int> myTree(bbox,0,0,nDescCell,-eps);
-  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
-  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
-  for(int i=0;i<nDescCell;i++)
-    {
-      std::vector<int> candidates;
-      myTree.getIntersectingElems(bbox+i*2*SPACEDIM,candidates);
-      for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
-        if(*it>i)
-          {
-            std::map<MCAuto<INTERP_KERNEL::Node>,int> m;
-            INTERP_KERNEL::Edge *e1(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coords,m)),
-                *e2(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[*it]],c+ci[*it]+1,coords,m));
-            INTERP_KERNEL::MergePoints merge;
-            INTERP_KERNEL::QuadraticPolygon c1,c2;
-            e1->intersectWith(e2,merge,c1,c2);
-            e1->decrRef(); e2->decrRef();
-            if(IKGeo2DInternalMapper(c1,m,c[ci[i]+1],c[ci[i]+2],intersectEdge[i]))
-              overlapEdge[i].push_back(*it);
-            if(IKGeo2DInternalMapper(c2,m,c[ci[*it]+1],c[ci[*it]+2],intersectEdge[*it]))
-              overlapEdge[*it].push_back(i);
-          }
-    }
-  // splitting done. sort intersect point in intersectEdge.
-  std::vector< std::vector<int> > middle(nDescCell);
-  int nbOf2DCellsToBeSplit(0);
-  bool middleNeedsToBeUsed(false);
-  std::vector<bool> cells2DToTreat(nDescCell,false);
-  for(int i=0;i<nDescCell;i++)
-    {
-      std::vector<int>& isect(intersectEdge[i]);
-      int sz((int)isect.size());
-      if(sz>1)
-        {
-          std::map<MCAuto<INTERP_KERNEL::Node>,int> m;
-          INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coords,m));
-          e->sortSubNodesAbs(coords,isect);
-          e->decrRef();
-        }
-      if(sz!=0)
-        {
-          int idx0(rdi[i]),idx1(rdi[i+1]);
-          if(idx1-idx0!=1)
-            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : internal error #0 !");
-          if(!cells2DToTreat[rd[idx0]])
-            {
-              cells2DToTreat[rd[idx0]]=true;
-              nbOf2DCellsToBeSplit++;
-            }
-          // try to reuse at most eventual 'middle' of SEG3
-          std::vector<int>& mid(middle[i]);
-          mid.resize(sz+1,-1);
-          if((INTERP_KERNEL::NormalizedCellType)c[ci[i]]==INTERP_KERNEL::NORM_SEG3)
-            {
-              middleNeedsToBeUsed=true;
-              const std::vector<int>& candidates(overlapEdge[i]);
-              std::vector<int> trueCandidates;
-              for(std::vector<int>::const_iterator itc=candidates.begin();itc!=candidates.end();itc++)
-                if((INTERP_KERNEL::NormalizedCellType)c[ci[*itc]]==INTERP_KERNEL::NORM_SEG3)
-                  trueCandidates.push_back(*itc);
-              int stNode(c[ci[i]+1]),endNode(isect[0]);
-              for(int j=0;j<sz+1;j++)
-                {
-                  for(std::vector<int>::const_iterator itc=trueCandidates.begin();itc!=trueCandidates.end();itc++)
-                    {
-                      int tmpSt(c[ci[*itc]+1]),tmpEnd(c[ci[*itc]+2]);
-                      if((tmpSt==stNode && tmpEnd==endNode) || (tmpSt==endNode && tmpEnd==stNode))
-                        { mid[j]=*itc; break; }
-                    }
-                  stNode=endNode;
-                  endNode=j<sz-1?isect[j+1]:c[ci[i]+2];
-                }
-            }
-        }
-    }
-  MCAuto<DataArrayInt> ret(DataArrayInt::New()),notRet(DataArrayInt::New()); ret->alloc(nbOf2DCellsToBeSplit,1);
-  if(nbOf2DCellsToBeSplit==0)
-    return ret.retn();
-  //
-  int *retPtr(ret->getPointer());
-  for(int i=0;i<nCell;i++)
-    if(cells2DToTreat[i])
-      *retPtr++=i;
-  //
-  MCAuto<DataArrayInt> mSafe,nSafe,oSafe,pSafe,qSafe,rSafe;
-  DataArrayInt *m(0),*n(0),*o(0),*p(0),*q(0),*r(0);
-  MEDCouplingUMesh::ExtractFromIndexedArrays(ret->begin(),ret->end(),desc1,descIndx1,m,n); mSafe=m; nSafe=n;
-  DataArrayInt::PutIntoToSkylineFrmt(intersectEdge,o,p); oSafe=o; pSafe=p;
-  if(middleNeedsToBeUsed)
-    { DataArrayInt::PutIntoToSkylineFrmt(middle,q,r); qSafe=q; rSafe=r; }
-  MCAuto<MEDCouplingUMesh> modif(static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(ret->begin(),ret->end(),true)));
-  int nbOfNodesCreated(modif->split2DCells(mSafe,nSafe,oSafe,pSafe,qSafe,rSafe));
-  setCoords(modif->getCoords());//if nbOfNodesCreated==0 modif and this have the same coordinates pointer so this line has no effect. But for quadratic cases this line is important.
-  setPartOfMySelf(ret->begin(),ret->end(),*modif);
-  {
-    bool areNodesMerged; int newNbOfNodes;
-    if(nbOfNodesCreated!=0)
-      MCAuto<DataArrayInt> tmp(mergeNodes(eps,areNodesMerged,newNbOfNodes));
-  }
-  return ret.retn();
-}
-
-/*!
- * This non const method works on 2D mesh. This method scans every cell in \a this and look if each edge constituting this cell is not mergeable with neighbors edges of that cell.
- * If yes, the cell is "repaired" to minimize at most its number of edges. So this method do not change the overall shape of cells in \a this (with eps precision).
- * This method do not take care of shared edges between cells, so this method can lead to a non conform mesh (\a this). If a conform mesh is required you're expected
- * to invoke MEDCouplingUMesh::mergeNodes and MEDCouplingUMesh::conformize2D right after this call.
- * This method works on any 2D geometric types of cell (even static one). If a cell is touched its type becomes dynamic automaticaly. For 2D "repaired" quadratic cells
- * new nodes for center of merged edges is are systematically created and appended at the end of the previously existing nodes.
- *
- * If the returned array is empty it means that nothing has changed in \a this (as if it were a const method). If the array is not empty the connectivity of \a this is modified
- * using new instance, idem for coordinates.
- *
- * If \a this is constituted by only linear 2D cells, this method is close to the computation of the convex hull of each cells in \a this.
- * 
- * \return DataArrayInt  * - The list of cellIds in \a this that have at least one edge colinearized.
- *
- * \throw If \a this is not coherent.
- * \throw If \a this has not spaceDim equal to 2.
- * \throw If \a this has not meshDim equal to 2.
- * 
- * \sa MEDCouplingUMesh::conformize2D, MEDCouplingUMesh::mergeNodes, MEDCouplingUMesh::convexEnvelop2D.
- */
-DataArrayInt *MEDCouplingUMesh::colinearize2D(double eps)
-{
-  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
-  checkConsistencyLight();
-  if(getSpaceDimension()!=2 || getMeshDimension()!=2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::colinearize2D : This method only works for meshes with spaceDim=2 and meshDim=2 !");
-  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
-  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
-  int nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
-  const int *cptr(_nodal_connec->begin()),*ciptr(_nodal_connec_index->begin());
-  MCAuto<DataArrayInt> newc(DataArrayInt::New()),newci(DataArrayInt::New()); newci->alloc(nbOfCells+1,1); newc->alloc(0,1); newci->setIJ(0,0,0);
-  MCAuto<DataArrayDouble> appendedCoords(DataArrayDouble::New()); appendedCoords->alloc(0,1);//1 not 2 it is not a bug.
-  const double *coords(_coords->begin());
-  int *newciptr(newci->getPointer());
-  for(int i=0;i<nbOfCells;i++,newciptr++,ciptr++)
-    {
-      if(Colinearize2DCell(coords,cptr+ciptr[0],cptr+ciptr[1],nbOfNodes,newc,appendedCoords))
-        ret->pushBackSilent(i);
-      newciptr[1]=newc->getNumberOfTuples();
-    }
-  //
-  if(ret->empty())
-    return ret.retn();
-  if(!appendedCoords->empty())
-    {
-      appendedCoords->rearrange(2);
-      MCAuto<DataArrayDouble> newCoords(DataArrayDouble::Aggregate(getCoords(),appendedCoords));//treat info on components
-      //non const part
-      setCoords(newCoords);
-    }
-  //non const part
-  setConnectivity(newc,newci,true);
-  return ret.retn();
-}
-
-/*!
- * \param [out] intersectEdge1 - for each cell in \a m1Desc returns the result of the split. The result is given using pair of int given resp start and stop.
- *                               So for all edge \a i in \a m1Desc \a  intersectEdge1[i] is of length 2*n where n is the number of sub edges.
- *                               And for each j in [1,n) intersect[i][2*(j-1)+1]==intersect[i][2*j].
- * \param [out] subDiv2 - for each cell in \a m2Desc returns nodes that split it using convention \a m1Desc first, then \a m2Desc, then addCoo
- * \param [out] colinear2 - for each cell in \a m2Desc returns the edges in \a m1Desc that are colinear to it.
- * \param [out] addCoo - nodes to be append at the end
- * \param [out] mergedNodes - gives all pair of nodes of \a m2Desc that have same location than some nodes in \a m1Desc. key is id in \a m2Desc offseted and value is id in \a m1Desc.
- */
-void MEDCouplingUMesh::Intersect1DMeshes(const MEDCouplingUMesh *m1Desc, const MEDCouplingUMesh *m2Desc, double eps,
-                                         std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& colinear2, std::vector< std::vector<int> >& subDiv2, std::vector<double>& addCoo, std::map<int,int>& mergedNodes)
-{
-  static const int SPACEDIM=2;
-  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
-  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
-  const int *c1(m1Desc->getNodalConnectivity()->begin()),*ci1(m1Desc->getNodalConnectivityIndex()->begin());
-  // Build BB tree of all edges in the tool mesh (second mesh)
-  MCAuto<DataArrayDouble> bbox1Arr(m1Desc->getBoundingBoxForBBTree()),bbox2Arr(m2Desc->getBoundingBoxForBBTree());
-  const double *bbox1(bbox1Arr->begin()),*bbox2(bbox2Arr->begin());
-  int nDescCell1(m1Desc->getNumberOfCells()),nDescCell2(m2Desc->getNumberOfCells());
-  intersectEdge1.resize(nDescCell1);
-  colinear2.resize(nDescCell2);
-  subDiv2.resize(nDescCell2);
-  BBTree<SPACEDIM,int> myTree(bbox2,0,0,m2Desc->getNumberOfCells(),-eps);
-
-  std::vector<int> candidates1(1);
-  int offset1(m1Desc->getNumberOfNodes());
-  int offset2(offset1+m2Desc->getNumberOfNodes());
-  for(int i=0;i<nDescCell1;i++)  // for all edges in the first mesh
-    {
-      std::vector<int> candidates2; // edges of mesh2 candidate for intersection
-      myTree.getIntersectingElems(bbox1+i*2*SPACEDIM,candidates2);
-      if(!candidates2.empty()) // candidates2 holds edges from the second mesh potentially intersecting current edge i in mesh1
-        {
-          std::map<INTERP_KERNEL::Node *,int> map1,map2;
-          // pol2 is not necessarily a closed polygon: just a set of (quadratic) edges (same as candidates2) in the Geometric DS format
-          INTERP_KERNEL::QuadraticPolygon *pol2=MEDCouplingUMeshBuildQPFromMesh(m2Desc,candidates2,map2);
-          candidates1[0]=i;
-          INTERP_KERNEL::QuadraticPolygon *pol1=MEDCouplingUMeshBuildQPFromMesh(m1Desc,candidates1,map1);
-          // This following part is to avoid that some removed nodes (for example due to a merge between pol1 and pol2) are replaced by a newly created one
-          // This trick guarantees that Node * are discriminant (i.e. form a unique identifier)
-          std::set<INTERP_KERNEL::Node *> nodes;
-          pol1->getAllNodes(nodes); pol2->getAllNodes(nodes);
-          std::size_t szz(nodes.size());
-          std::vector< MCAuto<INTERP_KERNEL::Node> > nodesSafe(szz);
-          std::set<INTERP_KERNEL::Node *>::const_iterator itt(nodes.begin());
-          for(std::size_t iii=0;iii<szz;iii++,itt++)
-            { (*itt)->incrRef(); nodesSafe[iii]=*itt; }
-          // end of protection
-          // Performs egde cutting:
-          pol1->splitAbs(*pol2,map1,map2,offset1,offset2,candidates2,intersectEdge1[i],i,colinear2,subDiv2,addCoo,mergedNodes);
-          delete pol2;
-          delete pol1;
-        }
-      else
-        // Copy the edge (take only the two first points, ie discard quadratic point at this stage)
-        intersectEdge1[i].insert(intersectEdge1[i].end(),c1+ci1[i]+1,c1+ci1[i]+3);
-    }
-}
-
-/*!
- * This method is private and is the first step of Partition of 2D mesh (spaceDim==2 and meshDim==2).
- * It builds the descending connectivity of the two meshes, and then using a binary tree
- * it computes the edge intersections. This results in new points being created : they're stored in addCoo.
- * Documentation about parameters  colinear2 and subDiv2 can be found in method QuadraticPolygon::splitAbs().
- */
-void MEDCouplingUMesh::IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,
-                                                   std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& colinear2, std::vector< std::vector<int> >& subDiv2,
-                                                   MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1,
-                                                   std::vector<double>& addCoo,
-                                                   MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2)
-{
-  // Build desc connectivity
-  desc1=DataArrayInt::New(); descIndx1=DataArrayInt::New(); revDesc1=DataArrayInt::New(); revDescIndx1=DataArrayInt::New();
-  desc2=DataArrayInt::New();
-  descIndx2=DataArrayInt::New();
-  revDesc2=DataArrayInt::New();
-  revDescIndx2=DataArrayInt::New();
-  MCAuto<DataArrayInt> dd1(desc1),dd2(descIndx1),dd3(revDesc1),dd4(revDescIndx1);
-  MCAuto<DataArrayInt> dd5(desc2),dd6(descIndx2),dd7(revDesc2),dd8(revDescIndx2);
-  m1Desc=m1->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1);
-  m2Desc=m2->buildDescendingConnectivity2(desc2,descIndx2,revDesc2,revDescIndx2);
-  MCAuto<MEDCouplingUMesh> dd9(m1Desc),dd10(m2Desc);
-  std::map<int,int> notUsedMap;
-  Intersect1DMeshes(m1Desc,m2Desc,eps,intersectEdge1,colinear2,subDiv2,addCoo,notUsedMap);
-  m1Desc->incrRef(); desc1->incrRef(); descIndx1->incrRef(); revDesc1->incrRef(); revDescIndx1->incrRef();
-  m2Desc->incrRef(); desc2->incrRef(); descIndx2->incrRef(); revDesc2->incrRef(); revDescIndx2->incrRef();
-}
-
-/*!
- * This method performs the 2nd step of Partition of 2D mesh.
- * This method has 4 inputs :
- *  - a mesh 'm1' with meshDim==1 and a SpaceDim==2
- *  - a mesh 'm2' with meshDim==1 and a SpaceDim==2
- *  - subDiv of size 'm2->getNumberOfCells()' that lists for each seg cell in 'm' the splitting node ids randomly sorted.
- * The aim of this method is to sort the splitting nodes, if any, and to put them in 'intersectEdge' output parameter based on edges of mesh 'm2'
- * Nodes end up lying consecutively on a cutted edge.
- * \param m1 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method.
- * (Only present for its coords in case of 'subDiv' shares some nodes of 'm1')
- * \param m2 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method.
- * \param addCoo input parameter with additional nodes linked to intersection of the 2 meshes.
- * \param[out] intersectEdge the same content as subDiv, but correclty oriented.
- */
-void MEDCouplingUMesh::BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2,
-                                           const std::vector<double>& addCoo,
-                                           const std::vector< std::vector<int> >& subDiv, std::vector< std::vector<int> >& intersectEdge)
-{
-  int offset1=m1->getNumberOfNodes();
-  int ncell=m2->getNumberOfCells();
-  const int *c=m2->getNodalConnectivity()->begin();
-  const int *cI=m2->getNodalConnectivityIndex()->begin();
-  const double *coo=m2->getCoords()->begin();
-  const double *cooBis=m1->getCoords()->begin();
-  int offset2=offset1+m2->getNumberOfNodes();
-  intersectEdge.resize(ncell);
-  for(int i=0;i<ncell;i++,cI++)
-    {
-      const std::vector<int>& divs=subDiv[i];
-      int nnode=cI[1]-cI[0]-1;
-      std::map<int, std::pair<INTERP_KERNEL::Node *,bool> > mapp2;
-      std::map<INTERP_KERNEL::Node *, int> mapp22;
-      for(int j=0;j<nnode;j++)
-        {
-          INTERP_KERNEL::Node *nn=new INTERP_KERNEL::Node(coo[2*c[(*cI)+j+1]],coo[2*c[(*cI)+j+1]+1]);
-          int nnid=c[(*cI)+j+1];
-          mapp2[nnid]=std::pair<INTERP_KERNEL::Node *,bool>(nn,true);
-          mapp22[nn]=nnid+offset1;
-        }
-      INTERP_KERNEL::Edge *e=MEDCouplingUMeshBuildQPFromEdge((INTERP_KERNEL::NormalizedCellType)c[*cI],mapp2,c+(*cI)+1);
-      for(std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >::const_iterator it=mapp2.begin();it!=mapp2.end();it++)
-        ((*it).second.first)->decrRef();
-      std::vector<INTERP_KERNEL::Node *> addNodes(divs.size());
-      std::map<INTERP_KERNEL::Node *,int> mapp3;
-      for(std::size_t j=0;j<divs.size();j++)
-        {
-          int id=divs[j];
-          INTERP_KERNEL::Node *tmp=0;
-          if(id<offset1)
-            tmp=new INTERP_KERNEL::Node(cooBis[2*id],cooBis[2*id+1]);
-          else if(id<offset2)
-            tmp=new INTERP_KERNEL::Node(coo[2*(id-offset1)],coo[2*(id-offset1)+1]);//if it happens, bad news mesh 'm2' is non conform.
-          else
-            tmp=new INTERP_KERNEL::Node(addCoo[2*(id-offset2)],addCoo[2*(id-offset2)+1]);
-          addNodes[j]=tmp;
-          mapp3[tmp]=id;
-        }
-      e->sortIdsAbs(addNodes,mapp22,mapp3,intersectEdge[i]);
-      for(std::vector<INTERP_KERNEL::Node *>::const_iterator it=addNodes.begin();it!=addNodes.end();it++)
-        (*it)->decrRef();
-      e->decrRef();
-    }
-}
-
-/*!
- * This method is part of the Slice3D algorithm. It is the first step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method).
- * This method allows to compute given the status of 3D curve cells and the descending connectivity 3DSurf->3DCurve to deduce the intersection of each 3D surf cells
- * with a plane. The result will be put in 'cut3DSuf' out parameter.
- * \param [in] cut3DCurve  input paramter that gives for each 3DCurve cell if it owns fully to the plane or partially.
- * \param [out] nodesOnPlane, returns all the nodes that are on the plane.
- * \param [in] nodal3DSurf is the nodal connectivity of 3D surf mesh.
- * \param [in] nodalIndx3DSurf is the nodal connectivity index of 3D surf mesh.
- * \param [in] nodal3DCurve is the nodal connectivity of 3D curve mesh.
- * \param [in] nodal3DIndxCurve is the nodal connectivity index of 3D curve mesh.
- * \param [in] desc is the descending connectivity 3DSurf->3DCurve
- * \param [in] descIndx is the descending connectivity index 3DSurf->3DCurve
- * \param [out] cut3DSuf input/output param.
- */
-void MEDCouplingUMesh::AssemblyForSplitFrom3DCurve(const std::vector<int>& cut3DCurve, std::vector<int>& nodesOnPlane, const int *nodal3DSurf, const int *nodalIndx3DSurf,
-                                                   const int *nodal3DCurve, const int *nodalIndx3DCurve,
-                                                   const int *desc, const int *descIndx, 
-                                                   std::vector< std::pair<int,int> >& cut3DSurf)
-{
-  std::set<int> nodesOnP(nodesOnPlane.begin(),nodesOnPlane.end());
-  int nbOf3DSurfCell=(int)cut3DSurf.size();
-  for(int i=0;i<nbOf3DSurfCell;i++)
-    {
-      std::vector<int> res;
-      int offset=descIndx[i];
-      int nbOfSeg=descIndx[i+1]-offset;
-      for(int j=0;j<nbOfSeg;j++)
-        {
-          int edgeId=desc[offset+j];
-          int status=cut3DCurve[edgeId];
-          if(status!=-2)
-            {
-              if(status>-1)
-                res.push_back(status);
-              else
-                {
-                  res.push_back(nodal3DCurve[nodalIndx3DCurve[edgeId]+1]);
-                  res.push_back(nodal3DCurve[nodalIndx3DCurve[edgeId]+2]);
-                }
-            }
-        }
-      switch(res.size())
-      {
-        case 2:
-          {
-            cut3DSurf[i].first=res[0]; cut3DSurf[i].second=res[1];
-            break;
-          }
-        case 1:
-        case 0:
-          {
-            std::set<int> s1(nodal3DSurf+nodalIndx3DSurf[i]+1,nodal3DSurf+nodalIndx3DSurf[i+1]);
-            std::set_intersection(nodesOnP.begin(),nodesOnP.end(),s1.begin(),s1.end(),std::back_insert_iterator< std::vector<int> >(res));
-            if(res.size()==2)
-              {
-                cut3DSurf[i].first=res[0]; cut3DSurf[i].second=res[1];
-              }
-            else
-              {
-                cut3DSurf[i].first=-1; cut3DSurf[i].second=-1;
-              }
-            break;
-          }
-        default:
-          {// case when plane is on a multi colinear edge of a polyhedron
-            if((int)res.size()==2*nbOfSeg)
-              {
-                cut3DSurf[i].first=-2; cut3DSurf[i].second=i;
-              }
-            else
-              throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AssemblyPointsFrom3DCurve : unexpected situation !");
-          }
-      }
-    }
-}
-
-/*!
- * \a this is expected to be a mesh with spaceDim==3 and meshDim==3. If not an exception will be thrown.
- * This method is part of the Slice3D algorithm. It is the second step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method).
- * This method allows to compute given the result of 3D surf cells with plane and the descending connectivity 3D->3DSurf to deduce the intersection of each 3D cells
- * with a plane. The result will be put in 'nodalRes' 'nodalResIndx' and 'cellIds' out parameters.
- * \param cut3DSurf  input paramter that gives for each 3DSurf its intersection with plane (result of MEDCouplingUMesh::AssemblyForSplitFrom3DCurve).
- * \param desc is the descending connectivity 3D->3DSurf
- * \param descIndx is the descending connectivity index 3D->3DSurf
- */
-void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair<int,int> >& cut3DSurf,
-                                                  const int *desc, const int *descIndx,
-                                                  DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const
-{
-  checkFullyDefined();
-  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::assemblyForSplitFrom3DSurf works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!");
-  const int *nodal3D(_nodal_connec->begin()),*nodalIndx3D(_nodal_connec_index->begin());
-  int nbOfCells(getNumberOfCells());
-  for(int i=0;i<nbOfCells;i++)
-    {
-      std::map<int, std::set<int> > m;
-      int offset=descIndx[i];
-      int nbOfFaces=descIndx[i+1]-offset;
-      int start=-1;
-      int end=-1;
-      for(int j=0;j<nbOfFaces;j++)
-        {
-          const std::pair<int,int>& p=cut3DSurf[desc[offset+j]];
-          if(p.first!=-1 && p.second!=-1)
-            {
-              if(p.first!=-2)
-                {
-                  start=p.first; end=p.second;
-                  m[p.first].insert(p.second);
-                  m[p.second].insert(p.first);
-                }
-              else
-                {
-                  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodal3D[nodalIndx3D[i]]);
-                  int sz=nodalIndx3D[i+1]-nodalIndx3D[i]-1;
-                  INTERP_KERNEL::AutoPtr<int> tmp=new int[sz];
-                  INTERP_KERNEL::NormalizedCellType cmsId;
-                  unsigned nbOfNodesSon=cm.fillSonCellNodalConnectivity2(j,nodal3D+nodalIndx3D[i]+1,sz,tmp,cmsId);
-                  start=tmp[0]; end=tmp[nbOfNodesSon-1];
-                  for(unsigned k=0;k<nbOfNodesSon;k++)
-                    {
-                      m[tmp[k]].insert(tmp[(k+1)%nbOfNodesSon]);
-                      m[tmp[(k+1)%nbOfNodesSon]].insert(tmp[k]);
-                    }
-                }
-            }
-        }
-      if(m.empty())
-        continue;
-      std::vector<int> conn(1,(int)INTERP_KERNEL::NORM_POLYGON);
-      int prev=end;
-      while(end!=start)
-        {
-          std::map<int, std::set<int> >::const_iterator it=m.find(start);
-          const std::set<int>& s=(*it).second;
-          std::set<int> s2; s2.insert(prev);
-          std::set<int> s3;
-          std::set_difference(s.begin(),s.end(),s2.begin(),s2.end(),inserter(s3,s3.begin()));
-          if(s3.size()==1)
-            {
-              int val=*s3.begin();
-              conn.push_back(start);
-              prev=start;
-              start=val;
-            }
-          else
-            start=end;
-        }
-      conn.push_back(end);
-      if(conn.size()>3)
-        {
-          nodalRes->insertAtTheEnd(conn.begin(),conn.end());
-          nodalResIndx->pushBackSilent(nodalRes->getNumberOfTuples());
-          cellIds->pushBackSilent(i);
-        }
-    }
-}
-
-void InsertNodeInConnIfNecessary(int nodeIdToInsert, std::vector<int>& conn, const double *coords, double eps)
+void MEDCouplingUMesh::reprQuickOverview(std::ostream& stream) const
 {
-  std::vector<int>::iterator it(std::find(conn.begin(),conn.end(),nodeIdToInsert));
-  if(it!=conn.end())
+  stream << "MEDCouplingUMesh C++ instance at " << this << ". Name : \"" << getName() << "\".";
+  if(_mesh_dim==-2)
+    { stream << " Not set !"; return ; }
+  stream << " Mesh dimension : " << _mesh_dim << ".";
+  if(_mesh_dim==-1)
     return ;
-  std::size_t sz(conn.size());
-  std::size_t found(std::numeric_limits<std::size_t>::max());
-  for(std::size_t i=0;i<sz;i++)
-    {
-      int pt0(conn[i]),pt1(conn[(i+1)%sz]);
-      double v1[3]={coords[3*pt1+0]-coords[3*pt0+0],coords[3*pt1+1]-coords[3*pt0+1],coords[3*pt1+2]-coords[3*pt0+2]},v2[3]={coords[3*nodeIdToInsert+0]-coords[3*pt0+0],coords[3*nodeIdToInsert+1]-coords[3*pt0+1],coords[3*nodeIdToInsert+2]-coords[3*pt0+2]};
-      double normm(sqrt(v1[0]*v1[0]+v1[1]*v1[1]+v1[2]*v1[2]));
-      std::transform(v1,v1+3,v1,std::bind2nd(std::multiplies<double>(),1./normm));
-      std::transform(v2,v2+3,v2,std::bind2nd(std::multiplies<double>(),1./normm));
-      double v3[3];
-      v3[0]=v1[1]*v2[2]-v1[2]*v2[1]; v3[1]=v1[2]*v2[0]-v1[0]*v2[2]; v3[2]=v1[0]*v2[1]-v1[1]*v2[0];
-      double normm2(sqrt(v3[0]*v3[0]+v3[1]*v3[1]+v3[2]*v3[2])),dotTest(v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]);
-      if(normm2<eps)
-        if(dotTest>eps && dotTest<1.-eps)
-          {
-            found=i;
-            break;
-          }
-    }
-  if(found==std::numeric_limits<std::size_t>::max())
-    throw INTERP_KERNEL::Exception("InsertNodeInConnIfNecessary : not found point !");
-  conn.insert(conn.begin()+(found+1)%sz,nodeIdToInsert);
+  if(!_coords)
+    { stream << " No coordinates set !"; return ; }
+  if(!_coords->isAllocated())
+    { stream << " Coordinates set but not allocated !"; return ; }
+  stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
+  stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
+  if(!_nodal_connec_index)
+    { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
+  if(!_nodal_connec_index->isAllocated())
+    { stream << std::endl << "Nodal connectivity set but not allocated !"; return ; }
+  int lgth=_nodal_connec_index->getNumberOfTuples();
+  int cpt=_nodal_connec_index->getNumberOfComponents();
+  if(cpt!=1 || lgth<1)
+    return ;
+  stream << std::endl << "Number of cells : " << lgth-1 << ".";
 }
 
-void SplitIntoToPart(const std::vector<int>& conn, int pt0, int pt1, std::vector<int>& part0, std::vector<int>& part1)
+std::string MEDCouplingUMesh::getVTKDataSetType() const
 {
-  std::size_t sz(conn.size());
-  std::vector<int> *curPart(&part0);
-  for(std::size_t i=0;i<sz;i++)
-    {
-      int nextt(conn[(i+1)%sz]);
-      (*curPart).push_back(nextt);
-      if(nextt==pt0 || nextt==pt1)
-        {
-          if(curPart==&part0)
-            curPart=&part1;
-          else
-            curPart=&part0;
-          (*curPart).push_back(nextt);
-        }
-    }
+  return std::string("UnstructuredGrid");
 }
 
-/*!
- * this method method splits cur cells 3D Surf in sub cells 3DSurf using the previous subsplit. This method is the last one used to clip.
+std::string MEDCouplingUMesh::getVTKFileExtension() const
+{
+  return std::string("vtu");
+}
+
+
+
+/**
+ * Provides a renumbering of the cells of this (which has to be a piecewise connected 1D line), so that
+ * the segments of the line are indexed in consecutive order (i.e. cells \a i and \a i+1 are neighbors).
+ * This doesn't modify the mesh. This method only works using nodal connectivity consideration. Coordinates of nodes are ignored here.
+ * The caller is to deal with the resulting DataArrayInt.
+ *  \throw If the coordinate array is not set.
+ *  \throw If the nodal connectivity of the cells is not defined.
+ *  \throw If m1 is not a mesh of dimension 2, or m1 is not a mesh of dimension 1
+ *  \throw If m2 is not a (piecewise) line (i.e. if a point has more than 2 adjacent segments)
+ *
+ * \sa DataArrayInt::sortEachPairToMakeALinkedList
  */
-void MEDCouplingUMesh::buildSubCellsFromCut(const std::vector< std::pair<int,int> >& cut3DSurf,
-                                            const int *desc, const int *descIndx, const double *coords, double eps,
-                                            std::vector<std::vector<int> >& res) const
+DataArrayInt *MEDCouplingUMesh::orderConsecutiveCells1D() const
 {
   checkFullyDefined();
-  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSubCellsFromCut works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!");
-  const int *nodal3D(_nodal_connec->begin()),*nodalIndx3D(_nodal_connec_index->begin());
-  int nbOfCells(getNumberOfCells());
-  if(nbOfCells!=1)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSubCellsFromCut works only with single cell presently !");
-  for(int i=0;i<nbOfCells;i++)
+  if(getMeshDimension()!=1)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orderConsecutiveCells1D works on unstructured mesh with meshdim = 1 !");
+
+  // Check that this is a line (and not a more complex 1D mesh) - each point is used at most by 2 segments:
+  MCAuto<DataArrayInt> _d(DataArrayInt::New()),_dI(DataArrayInt::New());
+  MCAuto<DataArrayInt> _rD(DataArrayInt::New()),_rDI(DataArrayInt::New());
+  MCAuto<MEDCouplingUMesh> m_points(buildDescendingConnectivity(_d, _dI, _rD, _rDI));
+  const int *d(_d->begin()), *dI(_dI->begin());
+  const int *rD(_rD->begin()), *rDI(_rDI->begin());
+  MCAuto<DataArrayInt> _dsi(_rDI->deltaShiftIndex());
+  const int * dsi(_dsi->begin());
+  MCAuto<DataArrayInt> dsii = _dsi->findIdsNotInRange(0,3);
+  m_points=0;
+  if (dsii->getNumberOfTuples())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orderConsecutiveCells1D only work with a mesh being a (piecewise) connected line!");
+
+  int nc(getNumberOfCells());
+  MCAuto<DataArrayInt> result(DataArrayInt::New());
+  result->alloc(nc,1);
+
+  // set of edges not used so far
+  std::set<int> edgeSet;
+  for (int i=0; i<nc; edgeSet.insert(i), i++);
+
+  int startSeg=0;
+  int newIdx=0;
+  // while we have points with only one neighbor segments
+  do
     {
-      int offset(descIndx[i]),nbOfFaces(descIndx[i+1]-offset),start(-1),end(-1);
-      for(int j=0;j<nbOfFaces;j++)
+      std::list<int> linePiece;
+      // fills a list of consecutive segment linked to startSeg. This can go forward or backward.
+      for (int direction=0;direction<2;direction++) // direction=0 --> forward, direction=1 --> backward
         {
-          const std::pair<int,int>& p=cut3DSurf[desc[offset+j]];
-          const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodal3D[nodalIndx3D[i]]));
-          int sz=nodalIndx3D[i+1]-nodalIndx3D[i]-1;
-          INTERP_KERNEL::AutoPtr<int> tmp(new int[sz]);
-          INTERP_KERNEL::NormalizedCellType cmsId;
-          unsigned nbOfNodesSon(cm.fillSonCellNodalConnectivity2(j,nodal3D+nodalIndx3D[i]+1,sz,tmp,cmsId));
-          std::vector<int> elt((int *)tmp,(int *)tmp+nbOfNodesSon);
-          if(p.first!=-1 && p.second!=-1)
+          // Fill the list forward (resp. backward) from the start segment:
+          int activeSeg = startSeg;
+          int prevPointId = -20;
+          int ptId;
+          while (!edgeSet.empty())
             {
-              if(p.first!=-2)
+              if (!(direction == 1 && prevPointId==-20)) // prevent adding twice startSeg
                 {
-                  InsertNodeInConnIfNecessary(p.first,elt,coords,eps);
-                  InsertNodeInConnIfNecessary(p.second,elt,coords,eps);
-                  std::vector<int> elt1,elt2;
-                  SplitIntoToPart(elt,p.first,p.second,elt1,elt2);
-                  res.push_back(elt1);
-                  res.push_back(elt2);
+                  if (direction==0)
+                    linePiece.push_back(activeSeg);
+                  else
+                    linePiece.push_front(activeSeg);
+                  edgeSet.erase(activeSeg);
                 }
-              else
-                res.push_back(elt);
+
+              int ptId1 = d[dI[activeSeg]], ptId2 = d[dI[activeSeg]+1];
+              ptId = direction ? (ptId1 == prevPointId ? ptId2 : ptId1) : (ptId2 == prevPointId ? ptId1 : ptId2);
+              if (dsi[ptId] == 1) // hitting the end of the line
+                break;
+              prevPointId = ptId;
+              int seg1 = rD[rDI[ptId]], seg2 = rD[rDI[ptId]+1];
+              activeSeg = (seg1 == activeSeg) ? seg2 : seg1;
             }
-          else
-            res.push_back(elt);
         }
+      // Done, save final piece into DA:
+      std::copy(linePiece.begin(), linePiece.end(), result->getPointer()+newIdx);
+      newIdx += linePiece.size();
+
+      // identify next valid start segment (one which is not consumed)
+      if(!edgeSet.empty())
+        startSeg = *(edgeSet.begin());
+    }
+  while (!edgeSet.empty());
+  return result.retn();
+}
+
+/**
+ * This method split some of edges of 2D cells in \a this. The edges to be split are specified in \a subNodesInSeg
+ * and in \a subNodesInSegI using \ref numbering-indirect storage mode.
+ * To do the work this method can optionally needs information about middle of subedges for quadratic cases if
+ * a minimal creation of new nodes is wanted.
+ * So this method try to reduce at most the number of new nodes. The only case that can lead this method to add
+ * nodes if a SEG3 is split without information of middle.
+ * \b WARNING : is returned value is different from 0 a call to MEDCouplingUMesh::mergeNodes is necessary to
+ * avoid to have a non conform mesh.
+ *
+ * \return int - the number of new nodes created (in most of cases 0).
+ * 
+ * \throw If \a this is not coherent.
+ * \throw If \a this has not spaceDim equal to 2.
+ * \throw If \a this has not meshDim equal to 2.
+ * \throw If some subcells needed to be split are orphan.
+ * \sa MEDCouplingUMesh::conformize2D
+ */
+int MEDCouplingUMesh::split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt, const DataArrayInt *midOptI)
+{
+  if(!desc || !descI || !subNodesInSeg || !subNodesInSegI)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : the 4 first arrays must be not null !");
+  desc->checkAllocated(); descI->checkAllocated(); subNodesInSeg->checkAllocated(); subNodesInSegI->checkAllocated();
+  if(getSpaceDimension()!=2 || getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : This method only works for meshes with spaceDim=2 and meshDim=2 !");
+  if(midOpt==0 && midOptI==0)
+    {
+      split2DCellsLinear(desc,descI,subNodesInSeg,subNodesInSegI);
+      return 0;
     }
+  else if(midOpt!=0 && midOptI!=0)
+    return split2DCellsQuadratic(desc,descI,subNodesInSeg,subNodesInSegI,midOpt,midOptI);
+  else
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : middle parameters must be set to null for all or not null for all.");
 }
 
 /*!
@@ -11499,47 +7927,6 @@ DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(const int *se
   return ComputeSpreadZoneGraduallyFromSeedAlg(fetched,seedBg,seedEnd,arrIn,arrIndxIn,nbOfDepthPeeling,nbOfDepthPeelingPerformed);
 }
 
-DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg(std::vector<bool>& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed)
-{
-  nbOfDepthPeelingPerformed=0;
-  if(!seedBg || !seedEnd || !arrIn || !arrIndxIn)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg : some input pointer is NULL !");
-  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
-  std::vector<bool> fetched2(nbOfTuples,false);
-  int i=0;
-  for(const int *seedElt=seedBg;seedElt!=seedEnd;seedElt++,i++)
-    {
-      if(*seedElt>=0 && *seedElt<nbOfTuples)
-        { fetched[*seedElt]=true; fetched2[*seedElt]=true; }
-      else
-        { std::ostringstream oss; oss << "MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg : At pos #" << i << " of seeds value is " << *seedElt << "! Should be in [0," << nbOfTuples << ") !"; throw INTERP_KERNEL::Exception(oss.str()); }
-    }
-  const int *arrInPtr=arrIn->begin();
-  const int *arrIndxPtr=arrIndxIn->begin();
-  int targetNbOfDepthPeeling=nbOfDepthPeeling!=-1?nbOfDepthPeeling:std::numeric_limits<int>::max();
-  std::vector<int> idsToFetch1(seedBg,seedEnd);
-  std::vector<int> idsToFetch2;
-  std::vector<int> *idsToFetch=&idsToFetch1;
-  std::vector<int> *idsToFetchOther=&idsToFetch2;
-  while(!idsToFetch->empty() && nbOfDepthPeelingPerformed<targetNbOfDepthPeeling)
-    {
-      for(std::vector<int>::const_iterator it=idsToFetch->begin();it!=idsToFetch->end();it++)
-        for(const int *it2=arrInPtr+arrIndxPtr[*it];it2!=arrInPtr+arrIndxPtr[*it+1];it2++)
-          if(!fetched[*it2])
-            { fetched[*it2]=true; fetched2[*it2]=true; idsToFetchOther->push_back(*it2); }
-      std::swap(idsToFetch,idsToFetchOther);
-      idsToFetchOther->clear();
-      nbOfDepthPeelingPerformed++;
-    }
-  int lgth=(int)std::count(fetched2.begin(),fetched2.end(),true);
-  i=0;
-  MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(lgth,1);
-  int *retPtr=ret->getPointer();
-  for(std::vector<bool>::const_iterator it=fetched2.begin();it!=fetched2.end();it++,i++)
-    if(*it)
-      *retPtr++=i;
-  return ret.retn();
-}
 
 /*!
  * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
@@ -11838,287 +8225,6 @@ MEDCoupling1SGTUMesh *MEDCouplingUMesh::tetrahedrize(int policy, DataArrayInt *&
   return ret0.retn();
 }
 
-/*!
- * It is the linear part of MEDCouplingUMesh::split2DCells. Here no additionnal nodes will be added in \b this. So coordinates pointer remain unchanged (is not even touch). 
- *
- * \sa MEDCouplingUMesh::split2DCells
- */
-void MEDCouplingUMesh::split2DCellsLinear(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI)
-{
-  checkConnectivityFullyDefined();
-  int ncells(getNumberOfCells()),lgthToReach(getNodalConnectivityArrayLen()+subNodesInSeg->getNumberOfTuples());
-  MCAuto<DataArrayInt> c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach);
-  const int *subPtr(subNodesInSeg->begin()),*subIPtr(subNodesInSegI->begin()),*descPtr(desc->begin()),*descIPtr(descI->begin()),*oldConn(getNodalConnectivity()->begin());
-  int *cPtr(c->getPointer()),*ciPtr(getNodalConnectivityIndex()->getPointer());
-  int prevPosOfCi(ciPtr[0]);
-  for(int i=0;i<ncells;i++,ciPtr++,descIPtr++)
-    {
-      int offset(descIPtr[0]),sz(descIPtr[1]-descIPtr[0]),deltaSz(0);
-      *cPtr++=(int)INTERP_KERNEL::NORM_POLYGON; *cPtr++=oldConn[prevPosOfCi+1];
-      for(int j=0;j<sz;j++)
-        {
-          int offset2(subIPtr[descPtr[offset+j]]),sz2(subIPtr[descPtr[offset+j]+1]-subIPtr[descPtr[offset+j]]);
-          for(int k=0;k<sz2;k++)
-            *cPtr++=subPtr[offset2+k];
-          if(j!=sz-1)
-            *cPtr++=oldConn[prevPosOfCi+j+2];
-          deltaSz+=sz2;
-        }
-      prevPosOfCi=ciPtr[1];
-      ciPtr[1]=ciPtr[0]+1+sz+deltaSz;//sz==old nb of nodes because (nb of subedges=nb of nodes for polygons)
-    }
-  if(c->end()!=cPtr)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCellsLinear : Some of edges to be split are orphan !");
-  _nodal_connec->decrRef();
-  _nodal_connec=c.retn(); _types.clear(); _types.insert(INTERP_KERNEL::NORM_POLYGON);
-}
-
-int InternalAddPoint(const INTERP_KERNEL::Edge *e, int id, const double *coo, int startId, int endId, DataArrayDouble& addCoo, int& nodesCnter)
-{
-  if(id!=-1)
-    return id;
-  else
-    {
-      int ret(nodesCnter++);
-      double newPt[2];
-      e->getMiddleOfPoints(coo+2*startId,coo+2*endId,newPt);
-      addCoo.insertAtTheEnd(newPt,newPt+2);
-      return ret;
-    }
-}
-
-int InternalAddPointOriented(const INTERP_KERNEL::Edge *e, int id, const double *coo, int startId, int endId, DataArrayDouble& addCoo, int& nodesCnter)
-{
-  if(id!=-1)
-    return id;
-  else
-    {
-      int ret(nodesCnter++);
-      double newPt[2];
-      e->getMiddleOfPointsOriented(coo+2*startId,coo+2*endId,newPt);
-      addCoo.insertAtTheEnd(newPt,newPt+2);
-      return ret;
-    }
-}
-
-
-/// @cond INTERNAL
-
-void EnterTheResultOf2DCellFirst(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector<int>& middles)
-{
-  int tmp[3];
-  int trueStart(start>=0?start:nbOfEdges+start);
-  tmp[0]=linOrArc?(int)INTERP_KERNEL::NORM_QPOLYG:(int)INTERP_KERNEL::NORM_POLYGON; tmp[1]=connBg[trueStart]; tmp[2]=connBg[stp];
-  newConnOfCell->insertAtTheEnd(tmp,tmp+3);
-  if(linOrArc)
-    {
-      if(stp-start>1)
-        {
-          int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2);
-          InternalAddPointOriented(e,-1,coords,tmp[1],tmp[2],*appendedCoords,tmp2);
-          middles.push_back(tmp3+offset);
-        }
-      else
-        middles.push_back(connBg[trueStart+nbOfEdges]);
-    }
-}
-
-void EnterTheResultOf2DCellMiddle(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector<int>& middles)
-{
-  int tmpSrt(newConnOfCell->back()),tmpEnd(connBg[stp]);
-  newConnOfCell->pushBackSilent(tmpEnd);
-  if(linOrArc)
-    {
-      if(stp-start>1)
-        {
-          int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2);
-          InternalAddPointOriented(e,-1,coords,tmpSrt,tmpEnd,*appendedCoords,tmp2);
-          middles.push_back(tmp3+offset);
-        }
-      else
-        middles.push_back(connBg[start+nbOfEdges]);
-    }
-}
-
-void EnterTheResultOf2DCellEnd(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector<int>& middles)
-{
-  // only the quadratic point to deal with:
-  if(linOrArc)
-    {
-      if(stp-start>1)
-        {
-          int tmpSrt(connBg[start]),tmpEnd(connBg[stp]);
-          int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2);
-          InternalAddPointOriented(e,-1,coords,tmpSrt,tmpEnd,*appendedCoords,tmp2);
-          middles.push_back(tmp3+offset);
-        }
-      else
-        middles.push_back(connBg[start+nbOfEdges]);
-    }
-}
-
-/// @endcond
-
-/*!
- * Returns true if a colinearization has been found in the given cell. If false is returned the content pushed in \a newConnOfCell is equal to [ \a connBg , \a connEnd ) .
- * \a appendedCoords is a DataArrayDouble instance with number of components equal to one (even if the items are pushed by pair).
- */
-bool MEDCouplingUMesh::Colinearize2DCell(const double *coords, const int *connBg, const int *connEnd, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords)
-{
-  std::size_t sz(std::distance(connBg,connEnd));
-  if(sz<3)//3 because 2+1(for the cell type) and 2 is the minimal number of edges of 2D cell.
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Colinearize2DCell : the input cell has invalid format !");
-  sz--;
-  INTERP_KERNEL::AutoPtr<int> tmpConn(new int[sz]);
-  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)connBg[0]));
-  unsigned nbs(cm.getNumberOfSons2(connBg+1,sz));
-  unsigned nbOfHit(0); // number of fusions operated
-  int posBaseElt(0),posEndElt(0),nbOfTurn(0);
-  const unsigned int maxNbOfHit = cm.isQuadratic() ? nbs-2 : nbs-3;  // a quad cell is authorized to end up with only two edges, a linear one has to keep 3 at least
-  INTERP_KERNEL::NormalizedCellType typeOfSon;
-  std::vector<int> middles;
-  bool ret(false);
-  for(;(nbOfTurn+nbOfHit)<nbs;nbOfTurn++)
-    {
-      cm.fillSonCellNodalConnectivity2(posBaseElt,connBg+1,sz,tmpConn,typeOfSon);
-      std::map<MCAuto<INTERP_KERNEL::Node>,int> m;
-      INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m));
-      posEndElt = posBaseElt+1;
-
-      // Look backward first: are the final edges of the cells colinear with the first ones?
-      // This initializes posBaseElt.
-      if(nbOfTurn==0)
-        {
-          for(unsigned i=1;i<nbs && nbOfHit<maxNbOfHit;i++) // 2nd condition is to avoid ending with a cell wih one single edge
-            {
-              cm.fillSonCellNodalConnectivity2(nbs-i,connBg+1,sz,tmpConn,typeOfSon);
-              INTERP_KERNEL::Edge *eCand(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m));
-              INTERP_KERNEL::EdgeIntersector *eint(INTERP_KERNEL::Edge::BuildIntersectorWith(e,eCand));
-              bool isColinear=eint->areColinears();
-              if(isColinear)
-                {
-                  nbOfHit++;
-                  posBaseElt--;
-                  ret=true;
-                }
-              delete eint;
-              eCand->decrRef();
-              if(!isColinear)
-                break;
-            }
-        }
-      // Now move forward:
-      const unsigned fwdStart = (nbOfTurn == 0 ? 0 : posBaseElt);  // the first element to be inspected going forward
-      for(unsigned j=fwdStart+1;j<nbs && nbOfHit<maxNbOfHit;j++)  // 2nd condition is to avoid ending with a cell wih one single edge
-        {
-          cm.fillSonCellNodalConnectivity2((int)j,connBg+1,sz,tmpConn,typeOfSon); // get edge #j's connectivity
-          INTERP_KERNEL::Edge *eCand(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m));
-          INTERP_KERNEL::EdgeIntersector *eint(INTERP_KERNEL::Edge::BuildIntersectorWith(e,eCand));
-          bool isColinear(eint->areColinears());
-          if(isColinear)
-            {
-              nbOfHit++;
-              posEndElt++;
-              ret=true;
-            }
-          delete eint;
-          eCand->decrRef();
-          if(!isColinear)
-              break;
-        }
-      //push [posBaseElt,posEndElt) in newConnOfCell using e
-      // The if clauses below are (volontary) not mutually exclusive: on a quad cell with 2 edges, the end of the connectivity is also its begining!
-      if(nbOfTurn==0)
-        // at the begining of the connectivity (insert type)
-        EnterTheResultOf2DCellFirst(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles);
-      else if((nbOfHit+nbOfTurn) != (nbs-1))
-        // in the middle
-        EnterTheResultOf2DCellMiddle(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles);
-      if ((nbOfHit+nbOfTurn) == (nbs-1))
-        // at the end (only quad points to deal with)
-        EnterTheResultOf2DCellEnd(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles);
-      posBaseElt=posEndElt;
-      e->decrRef();
-    }
-  if(!middles.empty())
-    newConnOfCell->insertAtTheEnd(middles.begin(),middles.end());
-  return ret;
-}
-
-/*!
- * It is the quadratic part of MEDCouplingUMesh::split2DCells. Here some additionnal nodes can be added at the end of coordinates array object.
- *
- * \return  int - the number of new nodes created.
- * \sa MEDCouplingUMesh::split2DCells
- */
-int MEDCouplingUMesh::split2DCellsQuadratic(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *mid, const DataArrayInt *midI)
-{
-  checkConsistencyLight();
-  int ncells(getNumberOfCells()),lgthToReach(getNodalConnectivityArrayLen()+2*subNodesInSeg->getNumberOfTuples()),nodesCnt(getNumberOfNodes());
-  MCAuto<DataArrayInt> c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach);
-  MCAuto<DataArrayDouble> addCoo(DataArrayDouble::New()); addCoo->alloc(0,1);
-  const int *subPtr(subNodesInSeg->begin()),*subIPtr(subNodesInSegI->begin()),*descPtr(desc->begin()),*descIPtr(descI->begin()),*oldConn(getNodalConnectivity()->begin());
-  const int *midPtr(mid->begin()),*midIPtr(midI->begin());
-  const double *oldCoordsPtr(getCoords()->begin());
-  int *cPtr(c->getPointer()),*ciPtr(getNodalConnectivityIndex()->getPointer());
-  int prevPosOfCi(ciPtr[0]);
-  for(int i=0;i<ncells;i++,ciPtr++,descIPtr++)
-    {
-      int offset(descIPtr[0]),sz(descIPtr[1]-descIPtr[0]),deltaSz(sz);
-      for(int j=0;j<sz;j++)
-        { int sz2(subIPtr[descPtr[offset+j]+1]-subIPtr[descPtr[offset+j]]); deltaSz+=sz2; }
-      *cPtr++=(int)INTERP_KERNEL::NORM_QPOLYG; cPtr[0]=oldConn[prevPosOfCi+1];
-      for(int j=0;j<sz;j++)//loop over subedges of oldConn
-        {
-          int offset2(subIPtr[descPtr[offset+j]]),sz2(subIPtr[descPtr[offset+j]+1]-subIPtr[descPtr[offset+j]]),offset3(midIPtr[descPtr[offset+j]]);
-          if(sz2==0)
-            {
-              if(j<sz-1)
-                cPtr[1]=oldConn[prevPosOfCi+2+j];
-              cPtr[deltaSz]=oldConn[prevPosOfCi+1+j+sz]; cPtr++;
-              continue;
-            }
-          std::vector<INTERP_KERNEL::Node *> ns(3);
-          ns[0]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+j]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+j]+1]);
-          ns[1]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+(1+j)%sz]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+(1+j)%sz]+1]);
-          ns[2]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+sz+j]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+sz+j]+1]);
-          MCAuto<INTERP_KERNEL::Edge> e(INTERP_KERNEL::QuadraticPolygon::BuildArcCircleEdge(ns));
-          for(int k=0;k<sz2;k++)//loop over subsplit of current subedge
-            {
-              cPtr[1]=subPtr[offset2+k];
-              cPtr[deltaSz]=InternalAddPoint(e,midPtr[offset3+k],oldCoordsPtr,cPtr[0],cPtr[1],*addCoo,nodesCnt); cPtr++;
-            }
-          int tmpEnd(oldConn[prevPosOfCi+1+(j+1)%sz]);
-          if(j!=sz-1)
-            { cPtr[1]=tmpEnd; }
-          cPtr[deltaSz]=InternalAddPoint(e,midPtr[offset3+sz2],oldCoordsPtr,cPtr[0],tmpEnd,*addCoo,nodesCnt); cPtr++;
-        }
-      prevPosOfCi=ciPtr[1]; cPtr+=deltaSz;
-      ciPtr[1]=ciPtr[0]+1+2*deltaSz;//sz==old nb of nodes because (nb of subedges=nb of nodes for polygons)
-    }
-  if(c->end()!=cPtr)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCellsQuadratic : Some of edges to be split are orphan !");
-  _nodal_connec->decrRef();
-  _nodal_connec=c.retn(); _types.clear(); _types.insert(INTERP_KERNEL::NORM_QPOLYG);
-  addCoo->rearrange(2);
-  MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(getCoords(),addCoo));//info are copied from getCoords() by using Aggregate
-  setCoords(coo);
-  return addCoo->getNumberOfTuples();
-}
-
-void MEDCouplingUMesh::ComputeAllTypesInternal(std::set<INTERP_KERNEL::NormalizedCellType>& types, const DataArrayInt *nodalConnec, const DataArrayInt *nodalConnecIndex)
-{
-  if(nodalConnec && nodalConnecIndex)
-    {
-      types.clear();
-      const int *conn(nodalConnec->begin()),*connIndex(nodalConnecIndex->begin());
-      int nbOfElem(nodalConnecIndex->getNbOfElems()-1);
-      if(nbOfElem>0)
-        for(const int *pt=connIndex;pt!=connIndex+nbOfElem;pt++)
-          types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]);
-    }
-}
-
 MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)),
     _own_cell(true),_cell_id(-1),_nb_cell(0)
 {
index ab2f47650fb37bb960c25051cf69b9ee4d62ef8d..7604a30c8d8e4523edaa53acb5b3f7ca3a7b03fb 100644 (file)
@@ -278,7 +278,8 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT DataArrayInt *buildUnionOf3DMesh() const;
     MEDCOUPLING_EXPORT DataArrayInt *orderConsecutiveCells1D() const;
     MEDCOUPLING_EXPORT MEDCouplingSkyLineArray *generateGraph() const;
-  private:
+  private: // all private methods are impl in MEDCouplingUMesh_internal.cxx
+
     MEDCouplingUMesh();
     MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy);
     ~MEDCouplingUMesh();
diff --git a/src/MEDCoupling/MEDCouplingUMesh_internal.cxx b/src/MEDCoupling/MEDCouplingUMesh_internal.cxx
new file mode 100644 (file)
index 0000000..5746888
--- /dev/null
@@ -0,0 +1,1756 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D
+//
+// 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, 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
+// 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
+//
+// Author : Anthony Geay (CEA/DEN)
+
+#include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingCMesh.hxx"
+#include "MEDCoupling1GTUMesh.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+#include "MEDCouplingSkyLineArray.hxx"
+#include "CellModel.hxx"
+#include "VolSurfUser.txx"
+#include "InterpolationUtils.hxx"
+#include "PointLocatorAlgos.txx"
+#include "BBTree.txx"
+#include "BBTreeDst.txx"
+#include "SplitterTetra.hxx"
+#include "DiameterCalculator.hxx"
+#include "DirectedBoundingBox.hxx"
+#include "InterpKernelMatrixTools.hxx"
+#include "InterpKernelMeshQuality.hxx"
+#include "InterpKernelCellSimplify.hxx"
+#include "InterpKernelGeo2DEdgeArcCircle.hxx"
+#include "InterpKernelAutoPtr.hxx"
+#include "InterpKernelGeo2DNode.hxx"
+#include "InterpKernelGeo2DEdgeLin.hxx"
+#include "InterpKernelGeo2DEdgeArcCircle.hxx"
+#include "InterpKernelGeo2DQuadraticPolygon.hxx"
+#include "MEDCouplingUMesh_internal.hxx"
+
+#include <sstream>
+#include <fstream>
+#include <numeric>
+#include <cstring>
+#include <limits>
+#include <list>
+
+using namespace MEDCoupling;
+
+/*!
+ * This method checks that all arrays are set. If yes nothing done if no an exception is thrown.
+ */
+void MEDCouplingUMesh::checkFullyDefined() const
+{
+  if(!_nodal_connec_index || !_nodal_connec || !_coords)
+    throw INTERP_KERNEL::Exception("Reverse nodal connectivity computation requires full connectivity and coordinates set in unstructured mesh.");
+}
+
+/*!
+ * This method checks that all connectivity arrays are set. If yes nothing done if no an exception is thrown.
+ */
+void MEDCouplingUMesh::checkConnectivityFullyDefined() const
+{
+  if(!_nodal_connec_index || !_nodal_connec)
+    throw INTERP_KERNEL::Exception("Reverse nodal connectivity computation requires full connectivity set in unstructured mesh.");
+}
+
+void MEDCouplingUMesh::reprConnectivityOfThisLL(std::ostringstream& stream) const
+{
+  if(_nodal_connec!=0 && _nodal_connec_index!=0)
+    {
+      int nbOfCells=getNumberOfCells();
+      const int *c=_nodal_connec->getConstPointer();
+      const int *ci=_nodal_connec_index->getConstPointer();
+      for(int i=0;i<nbOfCells;i++)
+        {
+          const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[i]]);
+          stream << "Cell #" << i << " " << cm.getRepr() << " : ";
+          std::copy(c+ci[i]+1,c+ci[i+1],std::ostream_iterator<int>(stream," "));
+          stream << "\n";
+        }
+    }
+  else
+    stream << "Connectivity not defined !\n";
+}
+
+
+/*!
+ * This method implements policy 0 of virtual method MEDCoupling::MEDCouplingUMesh::simplexize.
+ */
+DataArrayInt *MEDCouplingUMesh::simplexizePol0()
+{
+  checkConnectivityFullyDefined();
+  if(getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !");
+  int nbOfCells=getNumberOfCells();
+  MCAuto<DataArrayInt> ret=DataArrayInt::New();
+  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4);
+  ret->alloc(nbOfCells+nbOfCutCells,1);
+  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
+  int *retPt=ret->getPointer();
+  MCAuto<DataArrayInt> newConn=DataArrayInt::New();
+  MCAuto<DataArrayInt> newConnI=DataArrayInt::New();
+  newConnI->alloc(nbOfCells+nbOfCutCells+1,1);
+  newConn->alloc(getNodalConnectivityArrayLen()+3*nbOfCutCells,1);
+  int *pt=newConn->getPointer();
+  int *ptI=newConnI->getPointer();
+  ptI[0]=0;
+  const int *oldc=_nodal_connec->begin();
+  const int *ci=_nodal_connec_index->begin();
+  for(int i=0;i<nbOfCells;i++,ci++)
+    {
+      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_QUAD4)
+        {
+          const int tmp[8]={(int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+2],oldc[ci[0]+3],
+            (int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+3],oldc[ci[0]+4]};
+          pt=std::copy(tmp,tmp+8,pt);
+          ptI[1]=ptI[0]+4;
+          ptI[2]=ptI[0]+8;
+          *retPt++=i;
+          *retPt++=i;
+          ptI+=2;
+        }
+      else
+        {
+          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
+          ptI[1]=ptI[0]+ci[1]-ci[0];
+          ptI++;
+          *retPt++=i;
+        }
+    }
+  _nodal_connec->decrRef();
+  _nodal_connec=newConn.retn();
+  _nodal_connec_index->decrRef();
+  _nodal_connec_index=newConnI.retn();
+  computeTypes();
+  updateTime();
+  return ret.retn();
+}
+
+/*!
+ * This method implements policy 1 of virtual method MEDCoupling::MEDCouplingUMesh::simplexize.
+ */
+DataArrayInt *MEDCouplingUMesh::simplexizePol1()
+{
+  checkConnectivityFullyDefined();
+  if(getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !");
+  int nbOfCells=getNumberOfCells();
+  MCAuto<DataArrayInt> ret=DataArrayInt::New();
+  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4);
+  ret->alloc(nbOfCells+nbOfCutCells,1);
+  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
+  int *retPt=ret->getPointer();
+  MCAuto<DataArrayInt> newConn=DataArrayInt::New();
+  MCAuto<DataArrayInt> newConnI=DataArrayInt::New();
+  newConnI->alloc(nbOfCells+nbOfCutCells+1,1);
+  newConn->alloc(getNodalConnectivityArrayLen()+3*nbOfCutCells,1);
+  int *pt=newConn->getPointer();
+  int *ptI=newConnI->getPointer();
+  ptI[0]=0;
+  const int *oldc=_nodal_connec->begin();
+  const int *ci=_nodal_connec_index->begin();
+  for(int i=0;i<nbOfCells;i++,ci++)
+    {
+      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_QUAD4)
+        {
+          const int tmp[8]={(int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+2],oldc[ci[0]+4],
+            (int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+2],oldc[ci[0]+3],oldc[ci[0]+4]};
+          pt=std::copy(tmp,tmp+8,pt);
+          ptI[1]=ptI[0]+4;
+          ptI[2]=ptI[0]+8;
+          *retPt++=i;
+          *retPt++=i;
+          ptI+=2;
+        }
+      else
+        {
+          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
+          ptI[1]=ptI[0]+ci[1]-ci[0];
+          ptI++;
+          *retPt++=i;
+        }
+    }
+  _nodal_connec->decrRef();
+  _nodal_connec=newConn.retn();
+  _nodal_connec_index->decrRef();
+  _nodal_connec_index=newConnI.retn();
+  computeTypes();
+  updateTime();
+  return ret.retn();
+}
+
+/*!
+ * This method implements policy INTERP_KERNEL::PLANAR_FACE_5 of virtual method MEDCoupling::MEDCouplingUMesh::simplexize.
+ */
+DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace5()
+{
+  checkConnectivityFullyDefined();
+  if(getMeshDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace5 : this policy is only available for mesh with meshdim == 3 !");
+  int nbOfCells=getNumberOfCells();
+  MCAuto<DataArrayInt> ret=DataArrayInt::New();
+  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8);
+  ret->alloc(nbOfCells+4*nbOfCutCells,1);
+  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
+  int *retPt=ret->getPointer();
+  MCAuto<DataArrayInt> newConn=DataArrayInt::New();
+  MCAuto<DataArrayInt> newConnI=DataArrayInt::New();
+  newConnI->alloc(nbOfCells+4*nbOfCutCells+1,1);
+  newConn->alloc(getNodalConnectivityArrayLen()+16*nbOfCutCells,1);//21
+  int *pt=newConn->getPointer();
+  int *ptI=newConnI->getPointer();
+  ptI[0]=0;
+  const int *oldc=_nodal_connec->begin();
+  const int *ci=_nodal_connec_index->begin();
+  for(int i=0;i<nbOfCells;i++,ci++)
+    {
+      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_HEXA8)
+        {
+          for(int j=0;j<5;j++,pt+=5,ptI++)
+            {
+              pt[0]=(int)INTERP_KERNEL::NORM_TETRA4;
+              pt[1]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+0]+1]; pt[2]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+1]+1]; pt[3]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+2]+1]; pt[4]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+3]+1];
+              *retPt++=i;
+              ptI[1]=ptI[0]+5;
+            }
+        }
+      else
+        {
+          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
+          ptI[1]=ptI[0]+ci[1]-ci[0];
+          ptI++;
+          *retPt++=i;
+        }
+    }
+  _nodal_connec->decrRef();
+  _nodal_connec=newConn.retn();
+  _nodal_connec_index->decrRef();
+  _nodal_connec_index=newConnI.retn();
+  computeTypes();
+  updateTime();
+  return ret.retn();
+}
+
+/*!
+ * This method implements policy INTERP_KERNEL::PLANAR_FACE_6 of virtual method MEDCoupling::MEDCouplingUMesh::simplexize.
+ */
+DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace6()
+{
+  checkConnectivityFullyDefined();
+  if(getMeshDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace6 : this policy is only available for mesh with meshdim == 3 !");
+  int nbOfCells=getNumberOfCells();
+  MCAuto<DataArrayInt> ret=DataArrayInt::New();
+  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8);
+  ret->alloc(nbOfCells+5*nbOfCutCells,1);
+  if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); }
+  int *retPt=ret->getPointer();
+  MCAuto<DataArrayInt> newConn=DataArrayInt::New();
+  MCAuto<DataArrayInt> newConnI=DataArrayInt::New();
+  newConnI->alloc(nbOfCells+5*nbOfCutCells+1,1);
+  newConn->alloc(getNodalConnectivityArrayLen()+21*nbOfCutCells,1);
+  int *pt=newConn->getPointer();
+  int *ptI=newConnI->getPointer();
+  ptI[0]=0;
+  const int *oldc=_nodal_connec->begin();
+  const int *ci=_nodal_connec_index->begin();
+  for(int i=0;i<nbOfCells;i++,ci++)
+    {
+      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_HEXA8)
+        {
+          for(int j=0;j<6;j++,pt+=5,ptI++)
+            {
+              pt[0]=(int)INTERP_KERNEL::NORM_TETRA4;
+              pt[1]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+0]+1]; pt[2]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+1]+1]; pt[3]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+2]+1]; pt[4]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+3]+1];
+              *retPt++=i;
+              ptI[1]=ptI[0]+5;
+            }
+        }
+      else
+        {
+          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
+          ptI[1]=ptI[0]+ci[1]-ci[0];
+          ptI++;
+          *retPt++=i;
+        }
+    }
+  _nodal_connec->decrRef();
+  _nodal_connec=newConn.retn();
+  _nodal_connec_index->decrRef();
+  _nodal_connec_index=newConnI.retn();
+  computeTypes();
+  updateTime();
+  return ret.retn();
+}
+
+/*!
+ * Tessellates \a this 2D mesh by dividing not straight edges of quadratic faces,
+ * so that the number of cells remains the same. Quadratic faces are converted to
+ * polygons. This method works only for 2D meshes in
+ * 2D space. If no cells are quadratic (INTERP_KERNEL::NORM_QUAD8,
+ * INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QPOLYG ), \a this mesh remains unchanged.
+ * \warning This method can lead to a huge amount of nodes if \a eps is very low.
+ *  \param [in] eps - specifies the maximal angle (in radians) between 2 sub-edges of
+ *         a polylinized edge constituting the input polygon.
+ *  \throw If the coordinates array is not set.
+ *  \throw If the nodal connectivity of cells is not defined.
+ *  \throw If \a this->getMeshDimension() != 2.
+ *  \throw If \a this->getSpaceDimension() != 2.
+ */
+void MEDCouplingUMesh::tessellate2DInternal(double eps)
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=2 || getSpaceDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DInternal works on umeshes with meshdim equal to 2 and spaceDim equal to 2 too!");
+  double epsa=fabs(eps);
+  if(epsa<std::numeric_limits<double>::min())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DInternal : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !");
+  MCAuto<DataArrayInt> desc1(DataArrayInt::New()),descIndx1(DataArrayInt::New()),revDesc1(DataArrayInt::New()),revDescIndx1(DataArrayInt::New());
+  MCAuto<MEDCouplingUMesh> mDesc(buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1));
+  revDesc1=0; revDescIndx1=0;
+  mDesc->tessellate2D(eps);
+  subDivide2DMesh(mDesc->_nodal_connec->begin(),mDesc->_nodal_connec_index->begin(),desc1->begin(),descIndx1->begin());
+  setCoords(mDesc->getCoords());
+}
+
+/*!
+ * Tessellates \a this 1D mesh in 2D space by dividing not straight quadratic edges.
+ * \warning This method can lead to a huge amount of nodes if \a eps is very low.
+ *  \param [in] eps - specifies the maximal angle (in radian) between 2 sub-edges of
+ *         a sub-divided edge.
+ *  \throw If the coordinates array is not set.
+ *  \throw If the nodal connectivity of cells is not defined.
+ *  \throw If \a this->getMeshDimension() != 1.
+ *  \throw If \a this->getSpaceDimension() != 2.
+ */
+void MEDCouplingUMesh::tessellate2DCurveInternal(double eps)
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=1 || getSpaceDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurveInternal works on umeshes with meshdim equal to 1 and spaceDim equal to 2 too!");
+  double epsa=fabs(eps);
+  if(epsa<std::numeric_limits<double>::min())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurveInternal : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !");
+  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1.e-10;
+  int nbCells=getNumberOfCells();
+  int nbNodes=getNumberOfNodes();
+  const int *conn=_nodal_connec->begin();
+  const int *connI=_nodal_connec_index->begin();
+  const double *coords=_coords->begin();
+  std::vector<double> addCoo;
+  std::vector<int> newConn;//no direct DataArrayInt because interface with Geometric2D
+  MCAuto<DataArrayInt> newConnI(DataArrayInt::New());
+  newConnI->alloc(nbCells+1,1);
+  int *newConnIPtr=newConnI->getPointer();
+  *newConnIPtr=0;
+  int tmp1[3];
+  INTERP_KERNEL::Node *tmp2[3];
+  std::set<INTERP_KERNEL::NormalizedCellType> types;
+  for(int i=0;i<nbCells;i++,newConnIPtr++)
+    {
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
+      if(cm.isQuadratic())
+        {//assert(connI[i+1]-connI[i]-1==3)
+          tmp1[0]=conn[connI[i]+1+0]; tmp1[1]=conn[connI[i]+1+1]; tmp1[2]=conn[connI[i]+1+2];
+          tmp2[0]=new INTERP_KERNEL::Node(coords[2*tmp1[0]],coords[2*tmp1[0]+1]);
+          tmp2[1]=new INTERP_KERNEL::Node(coords[2*tmp1[1]],coords[2*tmp1[1]+1]);
+          tmp2[2]=new INTERP_KERNEL::Node(coords[2*tmp1[2]],coords[2*tmp1[2]+1]);
+          INTERP_KERNEL::EdgeArcCircle *eac=INTERP_KERNEL::EdgeArcCircle::BuildFromNodes(tmp2[0],tmp2[2],tmp2[1]);
+          if(eac)
+            {
+              eac->tesselate(tmp1,nbNodes,epsa,newConn,addCoo);
+              types.insert((INTERP_KERNEL::NormalizedCellType)newConn[newConnIPtr[0]]);
+              delete eac;
+              newConnIPtr[1]=(int)newConn.size();
+            }
+          else
+            {
+              types.insert(INTERP_KERNEL::NORM_SEG2);
+              newConn.push_back(INTERP_KERNEL::NORM_SEG2);
+              newConn.insert(newConn.end(),conn+connI[i]+1,conn+connI[i]+3);
+              newConnIPtr[1]=newConnIPtr[0]+3;
+            }
+        }
+      else
+        {
+          types.insert((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
+          newConn.insert(newConn.end(),conn+connI[i],conn+connI[i+1]);
+          newConnIPtr[1]=newConnIPtr[0]+3;
+        }
+    }
+  if(addCoo.empty() && ((int)newConn.size())==_nodal_connec->getNumberOfTuples())//nothing happens during tessellation : no update needed
+    return ;
+  _types=types;
+  DataArrayInt::SetArrayIn(newConnI,_nodal_connec_index);
+  MCAuto<DataArrayInt> newConnArr=DataArrayInt::New();
+  newConnArr->alloc((int)newConn.size(),1);
+  std::copy(newConn.begin(),newConn.end(),newConnArr->getPointer());
+  DataArrayInt::SetArrayIn(newConnArr,_nodal_connec);
+  MCAuto<DataArrayDouble> newCoords=DataArrayDouble::New();
+  newCoords->alloc(nbNodes+((int)addCoo.size())/2,2);
+  double *work=std::copy(_coords->begin(),_coords->end(),newCoords->getPointer());
+  std::copy(addCoo.begin(),addCoo.end(),work);
+  DataArrayDouble::SetArrayIn(newCoords,_coords);
+  updateTime();
+}
+
+
+/*!
+ * This private method is used to subdivide edges of a mesh with meshdim==2. If \a this has no a meshdim equal to 2 an exception will be thrown.
+ * This method completly ignore coordinates.
+ * \param nodeSubdived is the nodal connectivity of subdivision of edges
+ * \param nodeIndxSubdived is the nodal connectivity index of subdivision of edges
+ * \param desc is descending connectivity in format specified in MEDCouplingUMesh::buildDescendingConnectivity2
+ * \param descIndex is descending connectivity index in format specified in MEDCouplingUMesh::buildDescendingConnectivity2
+ */
+void MEDCouplingUMesh::subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex)
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::subDivide2DMesh : works only on umesh with meshdim==2 !");
+  int nbOfCells=getNumberOfCells();
+  int *connI=_nodal_connec_index->getPointer();
+  int newConnLgth=0;
+  for(int i=0;i<nbOfCells;i++,connI++)
+    {
+      int offset=descIndex[i];
+      int nbOfEdges=descIndex[i+1]-offset;
+      //
+      bool ddirect=desc[offset+nbOfEdges-1]>0;
+      int eedgeId=std::abs(desc[offset+nbOfEdges-1])-1;
+      int ref=ddirect?nodeSubdived[nodeIndxSubdived[eedgeId+1]-1]:nodeSubdived[nodeIndxSubdived[eedgeId]+1];
+      for(int j=0;j<nbOfEdges;j++)
+        {
+          bool direct=desc[offset+j]>0;
+          int edgeId=std::abs(desc[offset+j])-1;
+          if(!INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodeSubdived[nodeIndxSubdived[edgeId]]).isQuadratic())
+            {
+              int id1=nodeSubdived[nodeIndxSubdived[edgeId]+1];
+              int id2=nodeSubdived[nodeIndxSubdived[edgeId+1]-1];
+              int ref2=direct?id1:id2;
+              if(ref==ref2)
+                {
+                  int nbOfSubNodes=nodeIndxSubdived[edgeId+1]-nodeIndxSubdived[edgeId]-1;
+                  newConnLgth+=nbOfSubNodes-1;
+                  ref=direct?id2:id1;
+                }
+              else
+                {
+                  std::ostringstream oss; oss << "MEDCouplingUMesh::subDivide2DMesh : On polygon #" << i << " edgeid #" << j << " subedges mismatch : end subedge k!=start subedge k+1 !";
+                  throw INTERP_KERNEL::Exception(oss.str());
+                }
+            }
+          else
+            {
+              throw INTERP_KERNEL::Exception("MEDCouplingUMesh::subDivide2DMesh : this method only subdivides into linear edges !");
+            }
+        }
+      newConnLgth++;//+1 is for cell type
+      connI[1]=newConnLgth;
+    }
+  //
+  MCAuto<DataArrayInt> newConn=DataArrayInt::New();
+  newConn->alloc(newConnLgth,1);
+  int *work=newConn->getPointer();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      *work++=INTERP_KERNEL::NORM_POLYGON;
+      int offset=descIndex[i];
+      int nbOfEdges=descIndex[i+1]-offset;
+      for(int j=0;j<nbOfEdges;j++)
+        {
+          bool direct=desc[offset+j]>0;
+          int edgeId=std::abs(desc[offset+j])-1;
+          if(direct)
+            work=std::copy(nodeSubdived+nodeIndxSubdived[edgeId]+1,nodeSubdived+nodeIndxSubdived[edgeId+1]-1,work);
+          else
+            {
+              int nbOfSubNodes=nodeIndxSubdived[edgeId+1]-nodeIndxSubdived[edgeId]-1;
+              std::reverse_iterator<const int *> it(nodeSubdived+nodeIndxSubdived[edgeId+1]);
+              work=std::copy(it,it+nbOfSubNodes-1,work);
+            }
+        }
+    }
+  DataArrayInt::SetArrayIn(newConn,_nodal_connec);
+  _types.clear();
+  if(nbOfCells>0)
+    _types.insert(INTERP_KERNEL::NORM_POLYGON);
+}
+
+/*!
+ * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ).
+ * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
+ * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
+ * If \a fullyIn is true only cells whose ids are \b fully contained in [ \a begin,\a end ) tab will be kept.
+ *
+ * \param [in] begin input start of array of node ids.
+ * \param [in] end input end of array of node ids.
+ * \param [in] fullyIn input that specifies if all node ids must be in [ \a begin,\a end ) array to consider cell to be in.
+ * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
+ */
+void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
+{
+  MCAuto<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
+  checkConnectivityFullyDefined();
+  int tmp=-1;
+  int sz=getNodalConnectivity()->getMaxValue(tmp); sz=std::max(sz,0)+1;
+  std::vector<bool> fastFinder(sz,false);
+  for(const int *work=begin;work!=end;work++)
+    if(*work>=0 && *work<sz)
+      fastFinder[*work]=true;
+  int nbOfCells=getNumberOfCells();
+  const int *conn=getNodalConnectivity()->getConstPointer();
+  const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      int ref=0,nbOfHit=0;
+      for(const int *work2=conn+connIndex[i]+1;work2!=conn+connIndex[i+1];work2++)
+        if(*work2>=0)
+          {
+            ref++;
+            if(fastFinder[*work2])
+              nbOfHit++;
+          }
+      if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
+        cellIdsKept->pushBackSilent(i);
+    }
+  cellIdsKeptArr=cellIdsKept.retn();
+}
+
+/*!
+ * This method works on a 3D curve linear mesh that is to say (meshDim==1 and spaceDim==3).
+ * If it is not the case an exception will be thrown.
+ * This method is non const because the coordinate of \a this can be appended with some new points issued from
+ * intersection of plane defined by ('origin','vec').
+ * This method has one in/out parameter : 'cut3DCurve'.
+ * Param 'cut3DCurve' is expected to be of size 'this->getNumberOfCells()'. For each i in [0,'this->getNumberOfCells()')
+ * if cut3DCurve[i]==-2, it means that for cell #i in \a this nothing has been detected previously.
+ * if cut3DCurve[i]==-1, it means that cell#i has been already detected to be fully part of plane defined by ('origin','vec').
+ * This method will throw an exception if \a this contains a non linear segment.
+ */
+void MEDCouplingUMesh::split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector<int>& cut3DCurve)
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=1 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane works on umeshes with meshdim equal to 1 and spaceDim equal to 3 !");
+  int ncells=getNumberOfCells();
+  int nnodes=getNumberOfNodes();
+  double vec2[3],vec3[3],vec4[3];
+  double normm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
+  if(normm<1e-6)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane : parameter 'vec' should have a norm2 greater than 1e-6 !");
+  vec2[0]=vec[0]/normm; vec2[1]=vec[1]/normm; vec2[2]=vec[2]/normm;
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coo=_coords->getConstPointer();
+  std::vector<double> addCoo;
+  for(int i=0;i<ncells;i++)
+    {
+      if(conn[connI[i]]==(int)INTERP_KERNEL::NORM_SEG2)
+        {
+          if(cut3DCurve[i]==-2)
+            {
+              int st=conn[connI[i]+1],endd=conn[connI[i]+2];
+              vec3[0]=coo[3*endd]-coo[3*st]; vec3[1]=coo[3*endd+1]-coo[3*st+1]; vec3[2]=coo[3*endd+2]-coo[3*st+2];
+              double normm2=sqrt(vec3[0]*vec3[0]+vec3[1]*vec3[1]+vec3[2]*vec3[2]);
+              double colin=std::abs((vec3[0]*vec2[0]+vec3[1]*vec2[1]+vec3[2]*vec2[2])/normm2);
+              if(colin>eps)//if colin<=eps -> current SEG2 is colinear to the input plane
+                {
+                  const double *st2=coo+3*st;
+                  vec4[0]=st2[0]-origin[0]; vec4[1]=st2[1]-origin[1]; vec4[2]=st2[2]-origin[2];
+                  double pos=-(vec4[0]*vec2[0]+vec4[1]*vec2[1]+vec4[2]*vec2[2])/((vec3[0]*vec2[0]+vec3[1]*vec2[1]+vec3[2]*vec2[2]));
+                  if(pos>eps && pos<1-eps)
+                    {
+                      int nNode=((int)addCoo.size())/3;
+                      vec4[0]=st2[0]+pos*vec3[0]; vec4[1]=st2[1]+pos*vec3[1]; vec4[2]=st2[2]+pos*vec3[2];
+                      addCoo.insert(addCoo.end(),vec4,vec4+3);
+                      cut3DCurve[i]=nnodes+nNode;
+                    }
+                }
+            }
+        }
+      else
+        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane : this method is only available for linear cell (NORM_SEG2) !");
+    }
+  if(!addCoo.empty())
+    {
+      int newNbOfNodes=nnodes+((int)addCoo.size())/3;
+      MCAuto<DataArrayDouble> coo2=DataArrayDouble::New();
+      coo2->alloc(newNbOfNodes,3);
+      double *tmp=coo2->getPointer();
+      tmp=std::copy(_coords->begin(),_coords->end(),tmp);
+      std::copy(addCoo.begin(),addCoo.end(),tmp);
+      DataArrayDouble::SetArrayIn(coo2,_coords);
+    }
+}
+
+/*!
+ * This method incarnates the policy 0 for MEDCouplingUMesh::buildExtrudedMesh method.
+ * \param mesh1D is the input 1D mesh used for translation computation.
+ * \return newCoords new coords filled by this method.
+ */
+DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const
+{
+  int oldNbOfNodes=getNumberOfNodes();
+  int nbOf1DCells=mesh1D->getNumberOfCells();
+  int spaceDim=getSpaceDimension();
+  DataArrayDouble *ret=DataArrayDouble::New();
+  std::vector<bool> isQuads;
+  int nbOfLevsInVec=isQuad?2*nbOf1DCells+1:nbOf1DCells+1;
+  ret->alloc(oldNbOfNodes*nbOfLevsInVec,spaceDim);
+  double *retPtr=ret->getPointer();
+  const double *coords=getCoords()->getConstPointer();
+  double *work=std::copy(coords,coords+spaceDim*oldNbOfNodes,retPtr);
+  std::vector<int> v;
+  std::vector<double> c;
+  double vec[3];
+  v.reserve(3);
+  c.reserve(6);
+  for(int i=0;i<nbOf1DCells;i++)
+    {
+      v.resize(0);
+      mesh1D->getNodeIdsOfCell(i,v);
+      c.resize(0);
+      mesh1D->getCoordinatesOfNode(v[isQuad?2:1],c);
+      mesh1D->getCoordinatesOfNode(v[0],c);
+      std::transform(c.begin(),c.begin()+spaceDim,c.begin()+spaceDim,vec,std::minus<double>());
+      for(int j=0;j<oldNbOfNodes;j++)
+        work=std::transform(vec,vec+spaceDim,retPtr+spaceDim*(i*oldNbOfNodes+j),work,std::plus<double>());
+      if(isQuad)
+        {
+          c.resize(0);
+          mesh1D->getCoordinatesOfNode(v[1],c);
+          mesh1D->getCoordinatesOfNode(v[0],c);
+          std::transform(c.begin(),c.begin()+spaceDim,c.begin()+spaceDim,vec,std::minus<double>());
+          for(int j=0;j<oldNbOfNodes;j++)
+            work=std::transform(vec,vec+spaceDim,retPtr+spaceDim*(i*oldNbOfNodes+j),work,std::plus<double>());
+        }
+    }
+  ret->copyStringInfoFrom(*getCoords());
+  return ret;
+}
+
+/*!
+ * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method.
+ * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation.
+ * \return newCoords new coords filled by this method.
+ */
+DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const
+{
+  if(mesh1D->getSpaceDimension()==2)
+    return fillExtCoordsUsingTranslAndAutoRotation2D(mesh1D,isQuad);
+  if(mesh1D->getSpaceDimension()==3)
+    return fillExtCoordsUsingTranslAndAutoRotation3D(mesh1D,isQuad);
+  throw INTERP_KERNEL::Exception("Not implemented rotation and translation alg. for spacedim other than 2 and 3 !");
+}
+
+/*!
+ * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method.
+ * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation.
+ * \return newCoords new coords filled by this method.
+ */
+DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const
+{
+  if(isQuad)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D : not implemented for quadratic cells !");
+  int oldNbOfNodes=getNumberOfNodes();
+  int nbOf1DCells=mesh1D->getNumberOfCells();
+  if(nbOf1DCells<2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D : impossible to detect any angle of rotation ! Change extrusion policy 1->0 !");
+  MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
+  int nbOfLevsInVec=nbOf1DCells+1;
+  ret->alloc(oldNbOfNodes*nbOfLevsInVec,2);
+  double *retPtr=ret->getPointer();
+  retPtr=std::copy(getCoords()->getConstPointer(),getCoords()->getConstPointer()+getCoords()->getNbOfElems(),retPtr);
+  MCAuto<MEDCouplingUMesh> tmp=MEDCouplingUMesh::New();
+  MCAuto<DataArrayDouble> tmp2=getCoords()->deepCopy();
+  tmp->setCoords(tmp2);
+  const double *coo1D=mesh1D->getCoords()->getConstPointer();
+  const int *conn1D=mesh1D->getNodalConnectivity()->getConstPointer();
+  const int *connI1D=mesh1D->getNodalConnectivityIndex()->getConstPointer();
+  for(int i=1;i<nbOfLevsInVec;i++)
+    {
+      const double *begin=coo1D+2*conn1D[connI1D[i-1]+1];
+      const double *end=coo1D+2*conn1D[connI1D[i-1]+2];
+      const double *third=i+1<nbOfLevsInVec?coo1D+2*conn1D[connI1D[i]+2]:coo1D+2*conn1D[connI1D[i-2]+1];
+      const double vec[2]={end[0]-begin[0],end[1]-begin[1]};
+      tmp->translate(vec);
+      double tmp3[2],radius,alpha,alpha0;
+      const double *p0=i+1<nbOfLevsInVec?begin:third;
+      const double *p1=i+1<nbOfLevsInVec?end:begin;
+      const double *p2=i+1<nbOfLevsInVec?third:end;
+      INTERP_KERNEL::EdgeArcCircle::GetArcOfCirclePassingThru(p0,p1,p2,tmp3,radius,alpha,alpha0);
+      double cosangle=i+1<nbOfLevsInVec?(p0[0]-tmp3[0])*(p1[0]-tmp3[0])+(p0[1]-tmp3[1])*(p1[1]-tmp3[1]):(p2[0]-tmp3[0])*(p1[0]-tmp3[0])+(p2[1]-tmp3[1])*(p1[1]-tmp3[1]);
+      double angle=acos(cosangle/(radius*radius));
+      tmp->rotate(end,0,angle);
+      retPtr=std::copy(tmp2->getConstPointer(),tmp2->getConstPointer()+tmp2->getNbOfElems(),retPtr);
+    }
+  return ret.retn();
+}
+
+/*!
+ * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method.
+ * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation.
+ * \return newCoords new coords filled by this method.
+ */
+DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const
+{
+  if(isQuad)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D : not implemented for quadratic cells !");
+  int oldNbOfNodes=getNumberOfNodes();
+  int nbOf1DCells=mesh1D->getNumberOfCells();
+  if(nbOf1DCells<2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D : impossible to detect any angle of rotation ! Change extrusion policy 1->0 !");
+  MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
+  int nbOfLevsInVec=nbOf1DCells+1;
+  ret->alloc(oldNbOfNodes*nbOfLevsInVec,3);
+  double *retPtr=ret->getPointer();
+  retPtr=std::copy(getCoords()->getConstPointer(),getCoords()->getConstPointer()+getCoords()->getNbOfElems(),retPtr);
+  MCAuto<MEDCouplingUMesh> tmp=MEDCouplingUMesh::New();
+  MCAuto<DataArrayDouble> tmp2=getCoords()->deepCopy();
+  tmp->setCoords(tmp2);
+  const double *coo1D=mesh1D->getCoords()->getConstPointer();
+  const int *conn1D=mesh1D->getNodalConnectivity()->getConstPointer();
+  const int *connI1D=mesh1D->getNodalConnectivityIndex()->getConstPointer();
+  for(int i=1;i<nbOfLevsInVec;i++)
+    {
+      const double *begin=coo1D+3*conn1D[connI1D[i-1]+1];
+      const double *end=coo1D+3*conn1D[connI1D[i-1]+2];
+      const double *third=i+1<nbOfLevsInVec?coo1D+3*conn1D[connI1D[i]+2]:coo1D+3*conn1D[connI1D[i-2]+1];
+      const double vec[3]={end[0]-begin[0],end[1]-begin[1],end[2]-begin[2]};
+      tmp->translate(vec);
+      double tmp3[2],radius,alpha,alpha0;
+      const double *p0=i+1<nbOfLevsInVec?begin:third;
+      const double *p1=i+1<nbOfLevsInVec?end:begin;
+      const double *p2=i+1<nbOfLevsInVec?third:end;
+      double vecPlane[3]={
+        (p1[1]-p0[1])*(p2[2]-p1[2])-(p1[2]-p0[2])*(p2[1]-p1[1]),
+        (p1[2]-p0[2])*(p2[0]-p1[0])-(p1[0]-p0[0])*(p2[2]-p1[2]),
+        (p1[0]-p0[0])*(p2[1]-p1[1])-(p1[1]-p0[1])*(p2[0]-p1[0]),
+      };
+      double norm=sqrt(vecPlane[0]*vecPlane[0]+vecPlane[1]*vecPlane[1]+vecPlane[2]*vecPlane[2]);
+      if(norm>1.e-7)
+        {
+          vecPlane[0]/=norm; vecPlane[1]/=norm; vecPlane[2]/=norm;
+          double norm2=sqrt(vecPlane[0]*vecPlane[0]+vecPlane[1]*vecPlane[1]);
+          double vec2[2]={vecPlane[1]/norm2,-vecPlane[0]/norm2};
+          double s2=norm2;
+          double c2=cos(asin(s2));
+          double m[3][3]={
+            {vec2[0]*vec2[0]*(1-c2)+c2, vec2[0]*vec2[1]*(1-c2), vec2[1]*s2},
+            {vec2[0]*vec2[1]*(1-c2), vec2[1]*vec2[1]*(1-c2)+c2, -vec2[0]*s2},
+            {-vec2[1]*s2, vec2[0]*s2, c2}
+          };
+          double p0r[3]={m[0][0]*p0[0]+m[0][1]*p0[1]+m[0][2]*p0[2], m[1][0]*p0[0]+m[1][1]*p0[1]+m[1][2]*p0[2], m[2][0]*p0[0]+m[2][1]*p0[1]+m[2][2]*p0[2]};
+          double p1r[3]={m[0][0]*p1[0]+m[0][1]*p1[1]+m[0][2]*p1[2], m[1][0]*p1[0]+m[1][1]*p1[1]+m[1][2]*p1[2], m[2][0]*p1[0]+m[2][1]*p1[1]+m[2][2]*p1[2]};
+          double p2r[3]={m[0][0]*p2[0]+m[0][1]*p2[1]+m[0][2]*p2[2], m[1][0]*p2[0]+m[1][1]*p2[1]+m[1][2]*p2[2], m[2][0]*p2[0]+m[2][1]*p2[1]+m[2][2]*p2[2]};
+          INTERP_KERNEL::EdgeArcCircle::GetArcOfCirclePassingThru(p0r,p1r,p2r,tmp3,radius,alpha,alpha0);
+          double cosangle=i+1<nbOfLevsInVec?(p0r[0]-tmp3[0])*(p1r[0]-tmp3[0])+(p0r[1]-tmp3[1])*(p1r[1]-tmp3[1]):(p2r[0]-tmp3[0])*(p1r[0]-tmp3[0])+(p2r[1]-tmp3[1])*(p1r[1]-tmp3[1]);
+          double angle=acos(cosangle/(radius*radius));
+          tmp->rotate(end,vecPlane,angle);
+        }
+      retPtr=std::copy(tmp2->getConstPointer(),tmp2->getConstPointer()+tmp2->getNbOfElems(),retPtr);
+    }
+  return ret.retn();
+}
+
+/*!
+ * This method is private because not easy to use for end user. This method is const contrary to
+ * MEDCouplingUMesh::buildExtrudedMesh method because this->_coords are expected to contain
+ * the coords sorted slice by slice.
+ * \param isQuad specifies presence of quadratic cells.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const
+{
+  int nbOf1DCells(getNumberOfNodes()/nbOfNodesOf1Lev-1);
+  int nbOf2DCells(getNumberOfCells());
+  int nbOf3DCells(nbOf2DCells*nbOf1DCells);
+  MEDCouplingUMesh *ret(MEDCouplingUMesh::New("Extruded",getMeshDimension()+1));
+  const int *conn(_nodal_connec->begin()),*connI(_nodal_connec_index->begin());
+  MCAuto<DataArrayInt> newConn(DataArrayInt::New()),newConnI(DataArrayInt::New());
+  newConnI->alloc(nbOf3DCells+1,1);
+  int *newConnIPtr(newConnI->getPointer());
+  *newConnIPtr++=0;
+  std::vector<int> newc;
+  for(int j=0;j<nbOf2DCells;j++)
+    {
+      AppendExtrudedCell(conn+connI[j],conn+connI[j+1],nbOfNodesOf1Lev,isQuad,newc);
+      *newConnIPtr++=(int)newc.size();
+    }
+  newConn->alloc((int)(newc.size())*nbOf1DCells,1);
+  int *newConnPtr(newConn->getPointer());
+  int deltaPerLev(isQuad?2*nbOfNodesOf1Lev:nbOfNodesOf1Lev);
+  newConnIPtr=newConnI->getPointer();
+  for(int iz=0;iz<nbOf1DCells;iz++)
+    {
+      if(iz!=0)
+        std::transform(newConnIPtr+1,newConnIPtr+1+nbOf2DCells,newConnIPtr+1+iz*nbOf2DCells,std::bind2nd(std::plus<int>(),newConnIPtr[iz*nbOf2DCells]));
+      const int *posOfTypeOfCell(newConnIPtr);
+      for(std::vector<int>::const_iterator iter=newc.begin();iter!=newc.end();iter++,newConnPtr++)
+        {
+          int icell((int)(iter-newc.begin()));//std::distance unfortunately cannot been called here in C++98
+          if(icell!=*posOfTypeOfCell)
+            {
+              if(*iter!=-1)
+                *newConnPtr=(*iter)+iz*deltaPerLev;
+              else
+                *newConnPtr=-1;
+            }
+          else
+            {
+              *newConnPtr=*iter;
+              posOfTypeOfCell++;
+            }
+        }
+    }
+  ret->setConnectivity(newConn,newConnI,true);
+  ret->setCoords(getCoords());
+  return ret;
+}
+
+
+/*!
+ * This method find in candidate pool defined by 'candidates' the cells equal following the polycy 'compType'.
+ * If any true is returned and the results will be put at the end of 'result' output parameter. If not false is returned
+ * and result remains unchanged.
+ * The semantic of 'compType' is specified in MEDCouplingPointSet::zipConnectivityTraducer method.
+ * If in 'candidates' pool -1 value is considered as an empty value.
+ * WARNING this method returns only ONE set of result !
+ */
+bool MEDCouplingUMesh::AreCellsEqualInPool(const std::vector<int>& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result)
+{
+  if(candidates.size()<1)
+    return false;
+  bool ret=false;
+  std::vector<int>::const_iterator iter=candidates.begin();
+  int start=(*iter++);
+  for(;iter!=candidates.end();iter++)
+    {
+      int status=AreCellsEqual(conn,connI,start,*iter,compType);
+      if(status!=0)
+        {
+          if(!ret)
+            {
+              result->pushBackSilent(start);
+              ret=true;
+            }
+          if(status==1)
+            result->pushBackSilent(*iter);
+          else
+            result->pushBackSilent(status==2?(*iter+1):-(*iter+1));
+        }
+    }
+  return ret;
+}
+
+/*!
+ * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf.
+ * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ).
+ * The return newly allocated mesh will share the same coordinates as \a this.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
+{
+  checkConnectivityFullyDefined();
+  int ncell=getNumberOfCells();
+  MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
+  ret->_mesh_dim=_mesh_dim;
+  ret->setCoords(_coords);
+  std::size_t nbOfElemsRet=std::distance(begin,end);
+  int *connIndexRet=(int *)malloc((nbOfElemsRet+1)*sizeof(int));
+  connIndexRet[0]=0;
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connIndex=_nodal_connec_index->getConstPointer();
+  int newNbring=0;
+  for(const int *work=begin;work!=end;work++,newNbring++)
+    {
+      if(*work>=0 && *work<ncell)
+        connIndexRet[newNbring+1]=connIndexRet[newNbring]+connIndex[*work+1]-connIndex[*work];
+      else
+        {
+          free(connIndexRet);
+          std::ostringstream oss; oss << "MEDCouplingUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
+          throw INTERP_KERNEL::Exception(oss.str());
+        }
+    }
+  int *connRet=(int *)malloc(connIndexRet[nbOfElemsRet]*sizeof(int));
+  int *connRetWork=connRet;
+  std::set<INTERP_KERNEL::NormalizedCellType> types;
+  for(const int *work=begin;work!=end;work++)
+    {
+      types.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*work]]);
+      connRetWork=std::copy(conn+connIndex[*work],conn+connIndex[*work+1],connRetWork);
+    }
+  MCAuto<DataArrayInt> connRetArr=DataArrayInt::New();
+  connRetArr->useArray(connRet,true,C_DEALLOC,connIndexRet[nbOfElemsRet],1);
+  MCAuto<DataArrayInt> connIndexRetArr=DataArrayInt::New();
+  connIndexRetArr->useArray(connIndexRet,true,C_DEALLOC,(int)nbOfElemsRet+1,1);
+  ret->setConnectivity(connRetArr,connIndexRetArr,false);
+  ret->_types=types;
+  ret->copyTinyInfoFrom(this);
+  return ret.retn();
+}
+
+/*!
+ * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelfSlice.
+ * CellIds are given using range specified by a start an end and step.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoordsSlice(int start, int end, int step) const
+{
+  checkFullyDefined();
+  int ncell=getNumberOfCells();
+  MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
+  ret->_mesh_dim=_mesh_dim;
+  ret->setCoords(_coords);
+  int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelfKeepCoordsSlice : ");
+  MCAuto<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(newNbOfCells+1,1);
+  int *newConnIPtr=newConnI->getPointer(); *newConnIPtr=0;
+  int work=start;
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connIndex=_nodal_connec_index->getConstPointer();
+  for(int i=0;i<newNbOfCells;i++,newConnIPtr++,work+=step)
+    {
+      if(work>=0 && work<ncell)
+        {
+          newConnIPtr[1]=newConnIPtr[0]+connIndex[work+1]-connIndex[work];
+        }
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::buildPartOfMySelfKeepCoordsSlice : On pos #" << i << " input cell id =" << work << " should be in [0," << ncell << ") !";
+          throw INTERP_KERNEL::Exception(oss.str());
+        }
+    }
+  MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(newConnIPtr[0],1);
+  int *newConnPtr=newConn->getPointer();
+  std::set<INTERP_KERNEL::NormalizedCellType> types;
+  work=start;
+  for(int i=0;i<newNbOfCells;i++,newConnIPtr++,work+=step)
+    {
+      types.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[work]]);
+      newConnPtr=std::copy(conn+connIndex[work],conn+connIndex[work+1],newConnPtr);
+    }
+  ret->setConnectivity(newConn,newConnI,false);
+  ret->_types=types;
+  ret->copyTinyInfoFrom(this);
+  return ret.retn();
+}
+
+
+int MEDCouplingFastNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2)
+{
+  return id;
+}
+
+int MEDCouplingOrientationSensitiveNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2)
+{
+  if(!compute)
+    return id+1;
+  else
+    {
+      if(cm.getOrientationStatus(nb,conn1,conn2))
+        return id+1;
+      else
+        return -(id+1);
+    }
+}
+
+
+/*!
+ * Implementes \a conversionType 0 for meshes with meshDim = 1, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
+ * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
+ * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic.
+ */
+DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic1D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
+{
+  MCAuto<DataArrayDouble> bary=computeCellCenterOfMass();
+  MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
+  MCAuto<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
+  MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
+  int nbOfCells=getNumberOfCells();
+  int nbOfNodes=getNumberOfNodes();
+  const int *cPtr=_nodal_connec->begin();
+  const int *icPtr=_nodal_connec_index->begin();
+  int lastVal=0,offset=nbOfNodes;
+  for(int i=0;i<nbOfCells;i++,icPtr++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
+      if(type==INTERP_KERNEL::NORM_SEG2)
+        {
+          types.insert(INTERP_KERNEL::NORM_SEG3);
+          newConn->pushBackSilent((int)INTERP_KERNEL::NORM_SEG3);
+          newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[0]+3);
+          newConn->pushBackSilent(offset++);
+          lastVal+=4;
+          newConnI->pushBackSilent(lastVal);
+          ret->pushBackSilent(i);
+        }
+      else
+        {
+          types.insert(type);
+          lastVal+=(icPtr[1]-icPtr[0]);
+          newConnI->pushBackSilent(lastVal);
+          newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
+        }
+    }
+  MCAuto<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end());
+  coords=DataArrayDouble::Aggregate(getCoords(),tmp); conn=newConn.retn(); connI=newConnI.retn();
+  return ret.retn();
+}
+
+DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
+{
+  MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
+  MCAuto<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
+  MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
+  //
+  const int *descPtr(desc->begin()),*descIPtr(descI->begin());
+  DataArrayInt *conn1D=0,*conn1DI=0;
+  std::set<INTERP_KERNEL::NormalizedCellType> types1D;
+  DataArrayDouble *coordsTmp=0;
+  MCAuto<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0;
+  MCAuto<DataArrayDouble> coordsTmpSafe(coordsTmp);
+  MCAuto<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI);
+  const int *c1DPtr=conn1D->begin();
+  const int *c1DIPtr=conn1DI->begin();
+  int nbOfCells=getNumberOfCells();
+  const int *cPtr=_nodal_connec->begin();
+  const int *icPtr=_nodal_connec_index->begin();
+  int lastVal=0;
+  for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++)
+    {
+      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
+      if(!cm.isQuadratic())
+        {
+          INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType();
+          types.insert(typ2); newConn->pushBackSilent(typ2);
+          newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]);
+          for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++)
+            newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]);
+          lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0]);
+          newConnI->pushBackSilent(lastVal);
+          ret->pushBackSilent(i);
+        }
+      else
+        {
+          types.insert(typ);
+          lastVal+=(icPtr[1]-icPtr[0]);
+          newConnI->pushBackSilent(lastVal);
+          newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
+        }
+    }
+  conn=newConn.retn(); connI=newConnI.retn(); coords=coordsTmpSafe.retn();
+  return ret.retn();
+}
+
+/*!
+ * Implementes \a conversionType 0 for meshes with meshDim = 2, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
+ * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
+ * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic.
+ */
+DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
+{
+  MCAuto<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
+  MCAuto<MEDCouplingUMesh> m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0;
+  return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types);
+}
+
+DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
+{
+  MCAuto<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
+  MCAuto<MEDCouplingUMesh> m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0;
+  //
+  MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
+  MCAuto<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
+  MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
+  //
+  MCAuto<DataArrayDouble> bary=computeCellCenterOfMass();
+  const int *descPtr(desc->begin()),*descIPtr(descI->begin());
+  DataArrayInt *conn1D=0,*conn1DI=0;
+  std::set<INTERP_KERNEL::NormalizedCellType> types1D;
+  DataArrayDouble *coordsTmp=0;
+  MCAuto<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0;
+  MCAuto<DataArrayDouble> coordsTmpSafe(coordsTmp);
+  MCAuto<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI);
+  const int *c1DPtr=conn1D->begin();
+  const int *c1DIPtr=conn1DI->begin();
+  int nbOfCells=getNumberOfCells();
+  const int *cPtr=_nodal_connec->begin();
+  const int *icPtr=_nodal_connec_index->begin();
+  int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples();
+  for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++)
+    {
+      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
+      if(!cm.isQuadratic())
+        {
+          INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType2();
+          types.insert(typ2); newConn->pushBackSilent(typ2);
+          newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]);
+          for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++)
+            newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]);
+          newConn->pushBackSilent(offset+ret->getNumberOfTuples());
+          lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+1;
+          newConnI->pushBackSilent(lastVal);
+          ret->pushBackSilent(i);
+        }
+      else
+        {
+          types.insert(typ);
+          lastVal+=(icPtr[1]-icPtr[0]);
+          newConnI->pushBackSilent(lastVal);
+          newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
+        }
+    }
+  MCAuto<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end());
+  coords=DataArrayDouble::Aggregate(coordsTmpSafe,tmp); conn=newConn.retn(); connI=newConnI.retn();
+  return ret.retn();
+}
+
+/*!
+ * Implementes \a conversionType 0 for meshes with meshDim = 3, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
+ * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
+ * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic.
+ */
+DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
+{
+  MCAuto<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
+  MCAuto<MEDCouplingUMesh> m1D=explode3DMeshTo1D(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0;
+  return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types);
+}
+
+DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
+{
+  MCAuto<DataArrayInt> desc2(DataArrayInt::New()),desc2I(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
+  MCAuto<MEDCouplingUMesh> m2D=buildDescendingConnectivityGen<MinusOneSonsGeneratorBiQuadratic>(desc2,desc2I,tmp2,tmp3,MEDCouplingFastNbrer); tmp2=0; tmp3=0;
+  MCAuto<DataArrayInt> desc1(DataArrayInt::New()),desc1I(DataArrayInt::New()),tmp4(DataArrayInt::New()),tmp5(DataArrayInt::New());
+  MCAuto<MEDCouplingUMesh> m1D=explode3DMeshTo1D(desc1,desc1I,tmp4,tmp5); tmp4=0; tmp5=0;
+  //
+  MCAuto<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
+  MCAuto<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
+  MCAuto<DataArrayInt> ret=DataArrayInt::New(),ret2=DataArrayInt::New(); ret->alloc(0,1); ret2->alloc(0,1);
+  //
+  MCAuto<DataArrayDouble> bary=computeCellCenterOfMass();
+  const int *descPtr(desc1->begin()),*descIPtr(desc1I->begin()),*desc2Ptr(desc2->begin()),*desc2IPtr(desc2I->begin());
+  DataArrayInt *conn1D=0,*conn1DI=0,*conn2D=0,*conn2DI=0;
+  std::set<INTERP_KERNEL::NormalizedCellType> types1D,types2D;
+  DataArrayDouble *coordsTmp=0,*coordsTmp2=0;
+  MCAuto<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=DataArrayInt::New(); ret1D->alloc(0,1);
+  MCAuto<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI);
+  MCAuto<DataArrayDouble> coordsTmpSafe(coordsTmp);
+  MCAuto<DataArrayInt> ret2D=m2D->convertLinearCellsToQuadratic2D1(conn2D,conn2DI,coordsTmp2,types2D); ret2D=DataArrayInt::New(); ret2D->alloc(0,1);
+  MCAuto<DataArrayDouble> coordsTmp2Safe(coordsTmp2);
+  MCAuto<DataArrayInt> conn2DSafe(conn2D),conn2DISafe(conn2DI);
+  const int *c1DPtr=conn1D->begin(),*c1DIPtr=conn1DI->begin(),*c2DPtr=conn2D->begin(),*c2DIPtr=conn2DI->begin();
+  int nbOfCells=getNumberOfCells();
+  const int *cPtr=_nodal_connec->begin();
+  const int *icPtr=_nodal_connec_index->begin();
+  int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples();
+  for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++,desc2IPtr++)
+    {
+      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
+      if(!cm.isQuadratic())
+        {
+          INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType2();
+          if(typ2==INTERP_KERNEL::NORM_ERROR)
+            {
+              std::ostringstream oss; oss << "MEDCouplingUMesh::convertLinearCellsToQuadratic3D1 : On cell #" << i << " the linear cell type does not support advanced quadratization !";
+              throw INTERP_KERNEL::Exception(oss.str());
+            }
+          types.insert(typ2); newConn->pushBackSilent(typ2);
+          newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]);
+          for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++)
+            newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]);
+          for(const int *d=desc2Ptr+desc2IPtr[0];d!=desc2Ptr+desc2IPtr[1];d++)
+            {
+              int nodeId2=c2DPtr[c2DIPtr[(*d)+1]-1];
+              int tmpPos=newConn->getNumberOfTuples();
+              newConn->pushBackSilent(nodeId2);
+              ret2D->pushBackSilent(nodeId2); ret1D->pushBackSilent(tmpPos);
+            }
+          newConn->pushBackSilent(offset+ret->getNumberOfTuples());
+          lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+(desc2IPtr[1]-desc2IPtr[0])+1;
+          newConnI->pushBackSilent(lastVal);
+          ret->pushBackSilent(i);
+        }
+      else
+        {
+          types.insert(typ);
+          lastVal+=(icPtr[1]-icPtr[0]);
+          newConnI->pushBackSilent(lastVal);
+          newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
+        }
+    }
+  MCAuto<DataArrayInt> diffRet2D=ret2D->getDifferentValues();
+  MCAuto<DataArrayInt> o2nRet2D=diffRet2D->invertArrayN2O2O2N(coordsTmp2Safe->getNumberOfTuples());
+  coordsTmp2Safe=coordsTmp2Safe->selectByTupleId(diffRet2D->begin(),diffRet2D->end());
+  MCAuto<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end());
+  std::vector<const DataArrayDouble *> v(3); v[0]=coordsTmpSafe; v[1]=coordsTmp2Safe; v[2]=tmp;
+  int *c=newConn->getPointer();
+  const int *cI(newConnI->begin());
+  for(const int *elt=ret1D->begin();elt!=ret1D->end();elt++)
+    c[*elt]=o2nRet2D->getIJ(c[*elt],0)+offset;
+  offset=coordsTmp2Safe->getNumberOfTuples();
+  for(const int *elt=ret->begin();elt!=ret->end();elt++)
+    c[cI[(*elt)+1]-1]+=offset;
+  coords=DataArrayDouble::Aggregate(v); conn=newConn.retn(); connI=newConnI.retn();
+  return ret.retn();
+}
+
+DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshLinear(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const
+{
+  int nbOfNodesExpected(skin->getNumberOfNodes());
+  const int *n2oPtr(n2o->begin());
+  MCAuto<DataArrayInt> revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New());
+  skin->getReverseNodalConnectivity(revNodal,revNodalI);
+  const int *revNodalPtr(revNodal->begin()),*revNodalIPtr(revNodalI->begin());
+  const int *nodalPtr(skin->getNodalConnectivity()->begin());
+  const int *nodalIPtr(skin->getNodalConnectivityIndex()->begin());
+  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1);
+  int *work(ret->getPointer());  *work++=INTERP_KERNEL::NORM_POLYGON;
+  if(nbOfNodesExpected<1)
+    return ret.retn();
+  int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]);
+  *work++=n2oPtr[prevNode];
+  for(int i=1;i<nbOfNodesExpected;i++)
+    {
+      if(nodalIPtr[prevCell+1]-nodalIPtr[prevCell]==3)
+        {
+          std::set<int> conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3);
+          conn.erase(prevNode);
+          if(conn.size()==1)
+            {
+              int curNode(*(conn.begin()));
+              *work++=n2oPtr[curNode];
+              std::set<int> shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]);
+              shar.erase(prevCell);
+              if(shar.size()==1)
+                {
+                  prevCell=*(shar.begin());
+                  prevNode=curNode;
+                }
+              else
+                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 2 !");
+            }
+          else
+            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 1 !");
+        }
+      else
+        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected cell !");
+    }
+  return ret.retn();
+}
+
+DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshQuadratic(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const
+{
+  int nbOfNodesExpected(skin->getNumberOfNodes());
+  int nbOfTurn(nbOfNodesExpected/2);
+  const int *n2oPtr(n2o->begin());
+  MCAuto<DataArrayInt> revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New());
+  skin->getReverseNodalConnectivity(revNodal,revNodalI);
+  const int *revNodalPtr(revNodal->begin()),*revNodalIPtr(revNodalI->begin());
+  const int *nodalPtr(skin->getNodalConnectivity()->begin());
+  const int *nodalIPtr(skin->getNodalConnectivityIndex()->begin());
+  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1);
+  int *work(ret->getPointer());  *work++=INTERP_KERNEL::NORM_QPOLYG;
+  if(nbOfNodesExpected<1)
+    return ret.retn();
+  int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]);
+  *work=n2oPtr[prevNode]; work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[0]+3]]; work++;
+  for(int i=1;i<nbOfTurn;i++)
+    {
+      if(nodalIPtr[prevCell+1]-nodalIPtr[prevCell]==4)
+        {
+          std::set<int> conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3);
+          conn.erase(prevNode);
+          if(conn.size()==1)
+            {
+              int curNode(*(conn.begin()));
+              *work=n2oPtr[curNode];
+              std::set<int> shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]);
+              shar.erase(prevCell);
+              if(shar.size()==1)
+                {
+                  int curCell(*(shar.begin()));
+                  work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[curCell]+3]];
+                  prevCell=curCell;
+                  prevNode=curNode;
+                  work++;
+                }
+              else
+                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 2 !");
+            }
+          else
+            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 1 !");
+        }
+      else
+        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected cell !");
+    }
+  return ret.retn();
+}
+
+MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesLL(const std::vector<const MEDCouplingUMesh *>& a)
+{
+  if(a.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::MergeUMeshes : input array must be NON EMPTY !");
+  std::vector<const MEDCouplingUMesh *>::const_iterator it=a.begin();
+  int meshDim=(*it)->getMeshDimension();
+  int nbOfCells=(*it)->getNumberOfCells();
+  int meshLgth=(*it++)->getNodalConnectivityArrayLen();
+  for(;it!=a.end();it++)
+    {
+      if(meshDim!=(*it)->getMeshDimension())
+        throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, MergeUMeshes impossible !");
+      nbOfCells+=(*it)->getNumberOfCells();
+      meshLgth+=(*it)->getNodalConnectivityArrayLen();
+    }
+  std::vector<const MEDCouplingPointSet *> aps(a.size());
+  std::copy(a.begin(),a.end(),aps.begin());
+  MCAuto<DataArrayDouble> pts=MergeNodesArray(aps);
+  MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("merge",meshDim);
+  ret->setCoords(pts);
+  MCAuto<DataArrayInt> c=DataArrayInt::New();
+  c->alloc(meshLgth,1);
+  int *cPtr=c->getPointer();
+  MCAuto<DataArrayInt> cI=DataArrayInt::New();
+  cI->alloc(nbOfCells+1,1);
+  int *cIPtr=cI->getPointer();
+  *cIPtr++=0;
+  int offset=0;
+  int offset2=0;
+  for(it=a.begin();it!=a.end();it++)
+    {
+      int curNbOfCell=(*it)->getNumberOfCells();
+      const int *curCI=(*it)->_nodal_connec_index->begin();
+      const int *curC=(*it)->_nodal_connec->begin();
+      cIPtr=std::transform(curCI+1,curCI+curNbOfCell+1,cIPtr,std::bind2nd(std::plus<int>(),offset));
+      for(int j=0;j<curNbOfCell;j++)
+        {
+          const int *src=curC+curCI[j];
+          *cPtr++=*src++;
+          for(;src!=curC+curCI[j+1];src++,cPtr++)
+            {
+              if(*src!=-1)
+                *cPtr=*src+offset2;
+              else
+                *cPtr=-1;
+            }
+        }
+      offset+=curCI[curNbOfCell];
+      offset2+=(*it)->getNumberOfNodes();
+    }
+  //
+  ret->setConnectivity(c,cI,true);
+  return ret.retn();
+}
+
+
+/*!
+ * \param [in] pt the start pointer (included) of the coordinates of the point
+ * \param [in] cellIdsBg the start pointer (included) of cellIds
+ * \param [in] cellIdsEnd the end pointer (excluded) of cellIds
+ * \param [in] nc nodal connectivity
+ * \param [in] ncI nodal connectivity index
+ * \param [in,out] ret0 the min distance between \a this and the external input point
+ * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned.
+ * \sa MEDCouplingUMesh::distanceToPoint, MEDCouplingUMesh::distanceToPoints
+ */
+void MEDCouplingUMesh::DistanceToPoint3DSurfAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId)
+{
+  cellId=-1;
+  ret0=std::numeric_limits<double>::max();
+  for(const int *zeCell=cellIdsBg;zeCell!=cellIdsEnd;zeCell++)
+    {
+      switch((INTERP_KERNEL::NormalizedCellType)nc[ncI[*zeCell]])
+      {
+        case INTERP_KERNEL::NORM_TRI3:
+          {
+            double tmp=INTERP_KERNEL::DistanceFromPtToTriInSpaceDim3(pt,coords+3*nc[ncI[*zeCell]+1],coords+3*nc[ncI[*zeCell]+2],coords+3*nc[ncI[*zeCell]+3]);
+            if(tmp<ret0)
+              { ret0=tmp; cellId=*zeCell; }
+            break;
+          }
+        case INTERP_KERNEL::NORM_QUAD4:
+        case INTERP_KERNEL::NORM_POLYGON:
+          {
+            double tmp=INTERP_KERNEL::DistanceFromPtToPolygonInSpaceDim3(pt,nc+ncI[*zeCell]+1,nc+ncI[*zeCell+1],coords);
+            if(tmp<ret0)
+              { ret0=tmp; cellId=*zeCell; }
+            break;
+          }
+        default:
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint3DSurfAlg : not managed cell type ! Supporting TRI3, QUAD4 and POLYGON !");
+      }
+    }
+}
+
+/*!
+ * \param [in] pt the start pointer (included) of the coordinates of the point
+ * \param [in] cellIdsBg the start pointer (included) of cellIds
+ * \param [in] cellIdsEnd the end pointer (excluded) of cellIds
+ * \param [in] nc nodal connectivity
+ * \param [in] ncI nodal connectivity index
+ * \param [in,out] ret0 the min distance between \a this and the external input point
+ * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned.
+ * \sa MEDCouplingUMesh::distanceToPoint, MEDCouplingUMesh::distanceToPoints
+ */
+void MEDCouplingUMesh::DistanceToPoint2DCurveAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId)
+{
+  cellId=-1;
+  ret0=std::numeric_limits<double>::max();
+  for(const int *zeCell=cellIdsBg;zeCell!=cellIdsEnd;zeCell++)
+    {
+      switch((INTERP_KERNEL::NormalizedCellType)nc[ncI[*zeCell]])
+      {
+        case INTERP_KERNEL::NORM_SEG2:
+          {
+            std::size_t uselessEntry=0;
+            double tmp=INTERP_KERNEL::SquareDistanceFromPtToSegInSpaceDim2(pt,coords+2*nc[ncI[*zeCell]+1],coords+2*nc[ncI[*zeCell]+2],uselessEntry);
+            tmp=sqrt(tmp);
+            if(tmp<ret0)
+              { ret0=tmp; cellId=*zeCell; }
+            break;
+          }
+        default:
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint2DCurveAlg : not managed cell type ! Supporting SEG2 !");
+      }
+    }
+}
+DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg(std::vector<bool>& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed)
+{
+  nbOfDepthPeelingPerformed=0;
+  if(!seedBg || !seedEnd || !arrIn || !arrIndxIn)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg : some input pointer is NULL !");
+  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
+  std::vector<bool> fetched2(nbOfTuples,false);
+  int i=0;
+  for(const int *seedElt=seedBg;seedElt!=seedEnd;seedElt++,i++)
+    {
+      if(*seedElt>=0 && *seedElt<nbOfTuples)
+        { fetched[*seedElt]=true; fetched2[*seedElt]=true; }
+      else
+        { std::ostringstream oss; oss << "MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg : At pos #" << i << " of seeds value is " << *seedElt << "! Should be in [0," << nbOfTuples << ") !"; throw INTERP_KERNEL::Exception(oss.str()); }
+    }
+  const int *arrInPtr=arrIn->begin();
+  const int *arrIndxPtr=arrIndxIn->begin();
+  int targetNbOfDepthPeeling=nbOfDepthPeeling!=-1?nbOfDepthPeeling:std::numeric_limits<int>::max();
+  std::vector<int> idsToFetch1(seedBg,seedEnd);
+  std::vector<int> idsToFetch2;
+  std::vector<int> *idsToFetch=&idsToFetch1;
+  std::vector<int> *idsToFetchOther=&idsToFetch2;
+  while(!idsToFetch->empty() && nbOfDepthPeelingPerformed<targetNbOfDepthPeeling)
+    {
+      for(std::vector<int>::const_iterator it=idsToFetch->begin();it!=idsToFetch->end();it++)
+        for(const int *it2=arrInPtr+arrIndxPtr[*it];it2!=arrInPtr+arrIndxPtr[*it+1];it2++)
+          if(!fetched[*it2])
+            { fetched[*it2]=true; fetched2[*it2]=true; idsToFetchOther->push_back(*it2); }
+      std::swap(idsToFetch,idsToFetchOther);
+      idsToFetchOther->clear();
+      nbOfDepthPeelingPerformed++;
+    }
+  int lgth=(int)std::count(fetched2.begin(),fetched2.end(),true);
+  i=0;
+  MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(lgth,1);
+  int *retPtr=ret->getPointer();
+  for(std::vector<bool>::const_iterator it=fetched2.begin();it!=fetched2.end();it++,i++)
+    if(*it)
+      *retPtr++=i;
+  return ret.retn();
+}
+
+/*!
+ * This method put in zip format into parameter 'zipFrmt' in full interlace mode.
+ * This format is often asked by INTERP_KERNEL algorithms to avoid many indirections into coordinates array.
+ */
+void MEDCouplingUMesh::FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt)
+{
+  double *w=zipFrmt;
+  if(spaceDim==3)
+    for(int i=0;i<nbOfNodesInCell;i++)
+      w=std::copy(coo+3*conn[i],coo+3*conn[i]+3,w);
+  else if(spaceDim==2)
+    {
+      for(int i=0;i<nbOfNodesInCell;i++)
+        {
+          w=std::copy(coo+2*conn[i],coo+2*conn[i]+2,w);
+          *w++=0.;
+        }
+    }
+  else
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::FillInCompact3DMode : Invalid spaceDim specified : must be 2 or 3 !");
+}
+
+/*!
+ * This method takes in input a cell defined by its MEDcouplingUMesh connectivity [ \a connBg , \a connEnd ) and returns its extruded cell by inserting the result at the end of ret.
+ * \param nbOfNodesPerLev in parameter that specifies the number of nodes of one slice of global dataset
+ * \param isQuad specifies the policy of connectivity.
+ * @ret in/out parameter in which the result will be append
+ */
+void MEDCouplingUMesh::AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector<int>& ret)
+{
+  INTERP_KERNEL::NormalizedCellType flatType=(INTERP_KERNEL::NormalizedCellType)connBg[0];
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(flatType);
+  ret.push_back(cm.getExtrudedType());
+  int deltaz=isQuad?2*nbOfNodesPerLev:nbOfNodesPerLev;
+  switch(flatType)
+  {
+    case INTERP_KERNEL::NORM_POINT1:
+      {
+        ret.push_back(connBg[1]);
+        ret.push_back(connBg[1]+nbOfNodesPerLev);
+        break;
+      }
+    case INTERP_KERNEL::NORM_SEG2:
+      {
+        int conn[4]={connBg[1],connBg[2],connBg[2]+deltaz,connBg[1]+deltaz};
+        ret.insert(ret.end(),conn,conn+4);
+        break;
+      }
+    case INTERP_KERNEL::NORM_SEG3:
+      {
+        int conn[8]={connBg[1],connBg[3],connBg[3]+deltaz,connBg[1]+deltaz,connBg[2],connBg[3]+nbOfNodesPerLev,connBg[2]+deltaz,connBg[1]+nbOfNodesPerLev};
+        ret.insert(ret.end(),conn,conn+8);
+        break;
+      }
+    case INTERP_KERNEL::NORM_QUAD4:
+      {
+        int conn[8]={connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz};
+        ret.insert(ret.end(),conn,conn+8);
+        break;
+      }
+    case INTERP_KERNEL::NORM_TRI3:
+      {
+        int conn[6]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz};
+        ret.insert(ret.end(),conn,conn+6);
+        break;
+      }
+    case INTERP_KERNEL::NORM_TRI6:
+      {
+        int conn[15]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4],connBg[5],connBg[6],connBg[4]+deltaz,connBg[5]+deltaz,connBg[6]+deltaz,
+          connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev};
+        ret.insert(ret.end(),conn,conn+15);
+        break;
+      }
+    case INTERP_KERNEL::NORM_QUAD8:
+      {
+        int conn[20]={
+          connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz,
+          connBg[5],connBg[6],connBg[7],connBg[8],connBg[5]+deltaz,connBg[6]+deltaz,connBg[7]+deltaz,connBg[8]+deltaz,
+          connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev,connBg[4]+nbOfNodesPerLev
+        };
+        ret.insert(ret.end(),conn,conn+20);
+        break;
+      }
+    case INTERP_KERNEL::NORM_POLYGON:
+      {
+        std::back_insert_iterator< std::vector<int> > ii(ret);
+        std::copy(connBg+1,connEnd,ii);
+        *ii++=-1;
+        std::reverse_iterator<const int *> rConnBg(connEnd);
+        std::reverse_iterator<const int *> rConnEnd(connBg+1);
+        std::transform(rConnBg,rConnEnd,ii,std::bind2nd(std::plus<int>(),deltaz));
+        std::size_t nbOfRadFaces=std::distance(connBg+1,connEnd);
+        for(std::size_t i=0;i<nbOfRadFaces;i++)
+          {
+            *ii++=-1;
+            int conn[4]={connBg[(i+1)%nbOfRadFaces+1],connBg[i+1],connBg[i+1]+deltaz,connBg[(i+1)%nbOfRadFaces+1]+deltaz};
+            std::copy(conn,conn+4,ii);
+          }
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("A flat type has been detected that has not its extruded representation !");
+  }
+}
+
+
+/*!
+ * This method is part of the Slice3D algorithm. It is the first step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method).
+ * This method allows to compute given the status of 3D curve cells and the descending connectivity 3DSurf->3DCurve to deduce the intersection of each 3D surf cells
+ * with a plane. The result will be put in 'cut3DSuf' out parameter.
+ * \param [in] cut3DCurve  input paramter that gives for each 3DCurve cell if it owns fully to the plane or partially.
+ * \param [out] nodesOnPlane, returns all the nodes that are on the plane.
+ * \param [in] nodal3DSurf is the nodal connectivity of 3D surf mesh.
+ * \param [in] nodalIndx3DSurf is the nodal connectivity index of 3D surf mesh.
+ * \param [in] nodal3DCurve is the nodal connectivity of 3D curve mesh.
+ * \param [in] nodal3DIndxCurve is the nodal connectivity index of 3D curve mesh.
+ * \param [in] desc is the descending connectivity 3DSurf->3DCurve
+ * \param [in] descIndx is the descending connectivity index 3DSurf->3DCurve
+ * \param [out] cut3DSuf input/output param.
+ */
+void MEDCouplingUMesh::AssemblyForSplitFrom3DCurve(const std::vector<int>& cut3DCurve, std::vector<int>& nodesOnPlane, const int *nodal3DSurf, const int *nodalIndx3DSurf,
+                                                   const int *nodal3DCurve, const int *nodalIndx3DCurve,
+                                                   const int *desc, const int *descIndx,
+                                                   std::vector< std::pair<int,int> >& cut3DSurf)
+{
+  std::set<int> nodesOnP(nodesOnPlane.begin(),nodesOnPlane.end());
+  int nbOf3DSurfCell=(int)cut3DSurf.size();
+  for(int i=0;i<nbOf3DSurfCell;i++)
+    {
+      std::vector<int> res;
+      int offset=descIndx[i];
+      int nbOfSeg=descIndx[i+1]-offset;
+      for(int j=0;j<nbOfSeg;j++)
+        {
+          int edgeId=desc[offset+j];
+          int status=cut3DCurve[edgeId];
+          if(status!=-2)
+            {
+              if(status>-1)
+                res.push_back(status);
+              else
+                {
+                  res.push_back(nodal3DCurve[nodalIndx3DCurve[edgeId]+1]);
+                  res.push_back(nodal3DCurve[nodalIndx3DCurve[edgeId]+2]);
+                }
+            }
+        }
+      switch(res.size())
+      {
+        case 2:
+          {
+            cut3DSurf[i].first=res[0]; cut3DSurf[i].second=res[1];
+            break;
+          }
+        case 1:
+        case 0:
+          {
+            std::set<int> s1(nodal3DSurf+nodalIndx3DSurf[i]+1,nodal3DSurf+nodalIndx3DSurf[i+1]);
+            std::set_intersection(nodesOnP.begin(),nodesOnP.end(),s1.begin(),s1.end(),std::back_insert_iterator< std::vector<int> >(res));
+            if(res.size()==2)
+              {
+                cut3DSurf[i].first=res[0]; cut3DSurf[i].second=res[1];
+              }
+            else
+              {
+                cut3DSurf[i].first=-1; cut3DSurf[i].second=-1;
+              }
+            break;
+          }
+        default:
+          {// case when plane is on a multi colinear edge of a polyhedron
+            if((int)res.size()==2*nbOfSeg)
+              {
+                cut3DSurf[i].first=-2; cut3DSurf[i].second=i;
+              }
+            else
+              throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AssemblyPointsFrom3DCurve : unexpected situation !");
+          }
+      }
+    }
+}
+
+
+/*!
+ * \a this is expected to be a mesh with spaceDim==3 and meshDim==3. If not an exception will be thrown.
+ * This method is part of the Slice3D algorithm. It is the second step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method).
+ * This method allows to compute given the result of 3D surf cells with plane and the descending connectivity 3D->3DSurf to deduce the intersection of each 3D cells
+ * with a plane. The result will be put in 'nodalRes' 'nodalResIndx' and 'cellIds' out parameters.
+ * \param cut3DSurf  input paramter that gives for each 3DSurf its intersection with plane (result of MEDCouplingUMesh::AssemblyForSplitFrom3DCurve).
+ * \param desc is the descending connectivity 3D->3DSurf
+ * \param descIndx is the descending connectivity index 3D->3DSurf
+ */
+void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair<int,int> >& cut3DSurf,
+                                                  const int *desc, const int *descIndx,
+                                                  DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::assemblyForSplitFrom3DSurf works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!");
+  const int *nodal3D(_nodal_connec->begin()),*nodalIndx3D(_nodal_connec_index->begin());
+  int nbOfCells(getNumberOfCells());
+  for(int i=0;i<nbOfCells;i++)
+    {
+      std::map<int, std::set<int> > m;
+      int offset=descIndx[i];
+      int nbOfFaces=descIndx[i+1]-offset;
+      int start=-1;
+      int end=-1;
+      for(int j=0;j<nbOfFaces;j++)
+        {
+          const std::pair<int,int>& p=cut3DSurf[desc[offset+j]];
+          if(p.first!=-1 && p.second!=-1)
+            {
+              if(p.first!=-2)
+                {
+                  start=p.first; end=p.second;
+                  m[p.first].insert(p.second);
+                  m[p.second].insert(p.first);
+                }
+              else
+                {
+                  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodal3D[nodalIndx3D[i]]);
+                  int sz=nodalIndx3D[i+1]-nodalIndx3D[i]-1;
+                  INTERP_KERNEL::AutoPtr<int> tmp=new int[sz];
+                  INTERP_KERNEL::NormalizedCellType cmsId;
+                  unsigned nbOfNodesSon=cm.fillSonCellNodalConnectivity2(j,nodal3D+nodalIndx3D[i]+1,sz,tmp,cmsId);
+                  start=tmp[0]; end=tmp[nbOfNodesSon-1];
+                  for(unsigned k=0;k<nbOfNodesSon;k++)
+                    {
+                      m[tmp[k]].insert(tmp[(k+1)%nbOfNodesSon]);
+                      m[tmp[(k+1)%nbOfNodesSon]].insert(tmp[k]);
+                    }
+                }
+            }
+        }
+      if(m.empty())
+        continue;
+      std::vector<int> conn(1,(int)INTERP_KERNEL::NORM_POLYGON);
+      int prev=end;
+      while(end!=start)
+        {
+          std::map<int, std::set<int> >::const_iterator it=m.find(start);
+          const std::set<int>& s=(*it).second;
+          std::set<int> s2; s2.insert(prev);
+          std::set<int> s3;
+          std::set_difference(s.begin(),s.end(),s2.begin(),s2.end(),inserter(s3,s3.begin()));
+          if(s3.size()==1)
+            {
+              int val=*s3.begin();
+              conn.push_back(start);
+              prev=start;
+              start=val;
+            }
+          else
+            start=end;
+        }
+      conn.push_back(end);
+      if(conn.size()>3)
+        {
+          nodalRes->insertAtTheEnd(conn.begin(),conn.end());
+          nodalResIndx->pushBackSilent(nodalRes->getNumberOfTuples());
+          cellIds->pushBackSilent(i);
+        }
+    }
+}
+
+
+void MEDCouplingUMesh::ComputeAllTypesInternal(std::set<INTERP_KERNEL::NormalizedCellType>& types, const DataArrayInt *nodalConnec, const DataArrayInt *nodalConnecIndex)
+{
+  if(nodalConnec && nodalConnecIndex)
+    {
+      types.clear();
+      const int *conn(nodalConnec->begin()),*connIndex(nodalConnecIndex->begin());
+      int nbOfElem(nodalConnecIndex->getNbOfElems()-1);
+      if(nbOfElem>0)
+        for(const int *pt=connIndex;pt!=connIndex+nbOfElem;pt++)
+          types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]);
+    }
+}
diff --git a/src/MEDCoupling/MEDCouplingUMesh_internal.hxx b/src/MEDCoupling/MEDCouplingUMesh_internal.hxx
new file mode 100644 (file)
index 0000000..a1be4e6
--- /dev/null
@@ -0,0 +1,280 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D
+//
+// 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, 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
+// 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
+//
+// Author : Anthony Geay (EdF)
+
+using namespace MEDCoupling;
+
+class MinusOneSonsGenerator
+{
+public:
+  MinusOneSonsGenerator(const INTERP_KERNEL::CellModel& cm):_cm(cm) { }
+  unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfSons2(conn,lgth); }
+  unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonCellNodalConnectivity2(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); }
+  static const int DELTA=1;
+private:
+  const INTERP_KERNEL::CellModel& _cm;
+};
+
+class MinusOneSonsGeneratorBiQuadratic
+{
+public:
+  MinusOneSonsGeneratorBiQuadratic(const INTERP_KERNEL::CellModel& cm):_cm(cm) { }
+  unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfSons2(conn,lgth); }
+  unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonCellNodalConnectivity4(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); }
+  static const int DELTA=1;
+private:
+  const INTERP_KERNEL::CellModel& _cm;
+};
+
+class MinusTwoSonsGenerator
+{
+public:
+  MinusTwoSonsGenerator(const INTERP_KERNEL::CellModel& cm):_cm(cm) { }
+  unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfEdgesIn3D(conn,lgth); }
+  unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonEdgesNodalConnectivity3D(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); }
+  static const int DELTA=2;
+private:
+  const INTERP_KERNEL::CellModel& _cm;
+};
+
+class MicroEdgesGenerator2D
+{
+public:
+  MicroEdgesGenerator2D(const INTERP_KERNEL::CellModel& cm):_cm(cm) { }
+  unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfMicroEdges(); }
+  unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillMicroEdgeNodalConnectivity(sonId,nodalConn,sonNodalConn,typeOfSon); }
+  static const int DELTA=1;
+private:
+  const INTERP_KERNEL::CellModel& _cm;
+};
+
+class MicroEdgesGenerator3D
+{
+public:
+  MicroEdgesGenerator3D(const INTERP_KERNEL::CellModel& cm):_cm(cm) { }
+  unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfMicroEdges(); }
+  unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillMicroEdgeNodalConnectivity(sonId,nodalConn,sonNodalConn,typeOfSon); }
+  static const int DELTA=2;
+private:
+  const INTERP_KERNEL::CellModel& _cm;
+};
+
+int MEDCouplingFastNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2);
+int MEDCouplingOrientationSensitiveNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2);
+
+namespace MEDCoupling
+{
+  template<const int SPACEDIMM>
+  class DummyClsMCUG
+  {
+  public:
+    static const int MY_SPACEDIM=SPACEDIMM;
+    static const int MY_MESHDIM=8;
+    typedef int MyConnType;
+    static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE;
+    // begin
+    // useless, but for windows compilation ...
+    const double* getCoordinatesPtr() const { return 0; }
+    const int* getConnectivityPtr() const { return 0; }
+    const int* getConnectivityIndexPtr() const { return 0; }
+    INTERP_KERNEL::NormalizedCellType getTypeOfElement(int) const { return (INTERP_KERNEL::NormalizedCellType)0; }
+    // end
+  };
+}
+
+template<int SPACEDIM>
+void MEDCouplingUMesh::getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints,
+                                                   double eps, MCAuto<DataArrayInt>& elts, MCAuto<DataArrayInt>& eltsIndex) const
+{
+  elts=DataArrayInt::New(); eltsIndex=DataArrayInt::New(); eltsIndex->alloc(nbOfPoints+1,1); eltsIndex->setIJ(0,0,0); elts->alloc(0,1);
+  int *eltsIndexPtr(eltsIndex->getPointer());
+  MCAuto<DataArrayDouble> bboxArr(getBoundingBoxForBBTree(eps));
+  const double *bbox(bboxArr->begin());
+  int nbOfCells=getNumberOfCells();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  double bb[2*SPACEDIM];
+  BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbOfCells,-eps);
+  for(int i=0;i<nbOfPoints;i++)
+    {
+      eltsIndexPtr[i+1]=eltsIndexPtr[i];
+      for(int j=0;j<SPACEDIM;j++)
+        {
+          bb[2*j]=pos[SPACEDIM*i+j];
+          bb[2*j+1]=pos[SPACEDIM*i+j];
+        }
+      std::vector<int> candidates;
+      myTree.getIntersectingElems(bb,candidates);
+      for(std::vector<int>::const_iterator iter=candidates.begin();iter!=candidates.end();iter++)
+        {
+          int sz(connI[(*iter)+1]-connI[*iter]-1);
+          INTERP_KERNEL::NormalizedCellType ct((INTERP_KERNEL::NormalizedCellType)conn[connI[*iter]]);
+          bool status(false);
+          if(ct!=INTERP_KERNEL::NORM_POLYGON && ct!=INTERP_KERNEL::NORM_QPOLYG)
+            status=INTERP_KERNEL::PointLocatorAlgos<DummyClsMCUG<SPACEDIM> >::isElementContainsPoint(pos+i*SPACEDIM,ct,coords,conn+connI[*iter]+1,sz,eps);
+          else
+            {
+              if(SPACEDIM!=2)
+                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellsContainingPointsAlg : not implemented yet for POLYGON and QPOLYGON in spaceDim 3 !");
+              INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
+              INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
+              std::vector<INTERP_KERNEL::Node *> nodes(sz);
+              INTERP_KERNEL::QuadraticPolygon *pol(0);
+              for(int j=0;j<sz;j++)
+                {
+                  int nodeId(conn[connI[*iter]+1+j]);
+                  nodes[j]=new INTERP_KERNEL::Node(coords[nodeId*SPACEDIM],coords[nodeId*SPACEDIM+1]);
+                }
+              if(!INTERP_KERNEL::CellModel::GetCellModel(ct).isQuadratic())
+                pol=INTERP_KERNEL::QuadraticPolygon::BuildLinearPolygon(nodes);
+              else
+                pol=INTERP_KERNEL::QuadraticPolygon::BuildArcCirclePolygon(nodes);
+              INTERP_KERNEL::Node *n(new INTERP_KERNEL::Node(pos[i*SPACEDIM],pos[i*SPACEDIM+1]));
+              double a(0.),b(0.),c(0.);
+              a=pol->normalizeMe(b,c); n->applySimilarity(b,c,a);
+              status=pol->isInOrOut2(n);
+              delete pol; n->decrRef();
+            }
+          if(status)
+            {
+              eltsIndexPtr[i+1]++;
+              elts->pushBackSilent(*iter);
+            }
+        }
+    }
+}
+
+/*!
+ * \b WARNING this method do the assumption that connectivity lies on the coordinates set.
+ * For speed reasons no check of this will be done.
+ */
+template<class SonsGenerator>
+MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const
+{
+  if(!desc || !descIndx || !revDesc || !revDescIndx)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildDescendingConnectivityGen : present of a null pointer in input !");
+  checkConnectivityFullyDefined();
+  int nbOfCells=getNumberOfCells();
+  int nbOfNodes=getNumberOfNodes();
+  MCAuto<DataArrayInt> revNodalIndx=DataArrayInt::New(); revNodalIndx->alloc(nbOfNodes+1,1); revNodalIndx->fillWithZero();
+  int *revNodalIndxPtr=revNodalIndx->getPointer();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connIndex=_nodal_connec_index->getConstPointer();
+  std::string name="Mesh constituent of "; name+=getName();
+  MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(name,getMeshDimension()-SonsGenerator::DELTA);
+  ret->setCoords(getCoords());
+  ret->allocateCells(2*nbOfCells);
+  descIndx->alloc(nbOfCells+1,1);
+  MCAuto<DataArrayInt> revDesc2(DataArrayInt::New()); revDesc2->reserve(2*nbOfCells);
+  int *descIndxPtr=descIndx->getPointer(); *descIndxPtr++=0;
+  for(int eltId=0;eltId<nbOfCells;eltId++,descIndxPtr++)
+    {
+      int pos=connIndex[eltId];
+      int posP1=connIndex[eltId+1];
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[pos]);
+      SonsGenerator sg(cm);
+      unsigned nbOfSons=sg.getNumberOfSons2(conn+pos+1,posP1-pos-1);
+      INTERP_KERNEL::AutoPtr<int> tmp=new int[posP1-pos];
+      for(unsigned i=0;i<nbOfSons;i++)
+        {
+          INTERP_KERNEL::NormalizedCellType cmsId;
+          unsigned nbOfNodesSon=sg.fillSonCellNodalConnectivity2(i,conn+pos+1,posP1-pos-1,tmp,cmsId);
+          for(unsigned k=0;k<nbOfNodesSon;k++)
+            if(tmp[k]>=0)
+              revNodalIndxPtr[tmp[k]+1]++;
+          ret->insertNextCell(cmsId,nbOfNodesSon,tmp);
+          revDesc2->pushBackSilent(eltId);
+        }
+      descIndxPtr[0]=descIndxPtr[-1]+(int)nbOfSons;
+    }
+  int nbOfCellsM1=ret->getNumberOfCells();
+  std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
+  MCAuto<DataArrayInt> revNodal=DataArrayInt::New(); revNodal->alloc(revNodalIndx->back(),1);
+  std::fill(revNodal->getPointer(),revNodal->getPointer()+revNodalIndx->back(),-1);
+  int *revNodalPtr=revNodal->getPointer();
+  const int *connM1=ret->getNodalConnectivity()->getConstPointer();
+  const int *connIndexM1=ret->getNodalConnectivityIndex()->getConstPointer();
+  for(int eltId=0;eltId<nbOfCellsM1;eltId++)
+    {
+      const int *strtNdlConnOfCurCell=connM1+connIndexM1[eltId]+1;
+      const int *endNdlConnOfCurCell=connM1+connIndexM1[eltId+1];
+      for(const int *iter=strtNdlConnOfCurCell;iter!=endNdlConnOfCurCell;iter++)
+        if(*iter>=0)//for polyhedrons
+          *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
+    }
+  //
+  DataArrayInt *commonCells=0,*commonCellsI=0;
+  FindCommonCellsAlg(3,0,ret->getNodalConnectivity(),ret->getNodalConnectivityIndex(),revNodal,revNodalIndx,commonCells,commonCellsI);
+  MCAuto<DataArrayInt> commonCellsTmp(commonCells),commonCellsITmp(commonCellsI);
+  const int *commonCellsPtr(commonCells->getConstPointer()),*commonCellsIPtr(commonCellsI->getConstPointer());
+  int newNbOfCellsM1=-1;
+  MCAuto<DataArrayInt> o2nM1=DataArrayInt::ConvertIndexArrayToO2N(nbOfCellsM1,commonCells->begin(),
+                                                                                                            commonCellsI->begin(),commonCellsI->end(),newNbOfCellsM1);
+  std::vector<bool> isImpacted(nbOfCellsM1,false);
+  for(const int *work=commonCellsI->begin();work!=commonCellsI->end()-1;work++)
+    for(int work2=work[0];work2!=work[1];work2++)
+      isImpacted[commonCellsPtr[work2]]=true;
+  const int *o2nM1Ptr=o2nM1->getConstPointer();
+  MCAuto<DataArrayInt> n2oM1=o2nM1->invertArrayO2N2N2OBis(newNbOfCellsM1);
+  const int *n2oM1Ptr=n2oM1->getConstPointer();
+  MCAuto<MEDCouplingUMesh> ret2=static_cast<MEDCouplingUMesh *>(ret->buildPartOfMySelf(n2oM1->begin(),n2oM1->end(),true));
+  ret2->copyTinyInfoFrom(this);
+  desc->alloc(descIndx->back(),1);
+  int *descPtr=desc->getPointer();
+  const INTERP_KERNEL::CellModel& cmsDft=INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_POINT1);
+  for(int i=0;i<nbOfCellsM1;i++,descPtr++)
+    {
+      if(!isImpacted[i])
+        *descPtr=nbrer(o2nM1Ptr[i],0,cmsDft,false,0,0);
+      else
+        {
+          if(i!=n2oM1Ptr[o2nM1Ptr[i]])
+            {
+              const INTERP_KERNEL::CellModel& cms=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)connM1[connIndexM1[i]]);
+              *descPtr=nbrer(o2nM1Ptr[i],connIndexM1[i+1]-connIndexM1[i]-1,cms,true,connM1+connIndexM1[n2oM1Ptr[o2nM1Ptr[i]]]+1,connM1+connIndexM1[i]+1);
+            }
+          else
+            *descPtr=nbrer(o2nM1Ptr[i],0,cmsDft,false,0,0);
+        }
+    }
+  revDesc->reserve(newNbOfCellsM1);
+  revDescIndx->alloc(newNbOfCellsM1+1,1);
+  int *revDescIndxPtr=revDescIndx->getPointer(); *revDescIndxPtr++=0;
+  const int *revDesc2Ptr=revDesc2->getConstPointer();
+  for(int i=0;i<newNbOfCellsM1;i++,revDescIndxPtr++)
+    {
+      int oldCellIdM1=n2oM1Ptr[i];
+      if(!isImpacted[oldCellIdM1])
+        {
+          revDesc->pushBackSilent(revDesc2Ptr[oldCellIdM1]);
+          revDescIndxPtr[0]=revDescIndxPtr[-1]+1;
+        }
+      else
+        {
+          for(int j=commonCellsIPtr[0];j<commonCellsIPtr[1];j++)
+            revDesc->pushBackSilent(revDesc2Ptr[commonCellsPtr[j]]);
+          revDescIndxPtr[0]=revDescIndxPtr[-1]+commonCellsIPtr[1]-commonCellsIPtr[0];
+          commonCellsIPtr++;
+        }
+    }
+  //
+  return ret2.retn();
+}
+
+
diff --git a/src/MEDCoupling/MEDCouplingUMesh_intersection.cxx b/src/MEDCoupling/MEDCouplingUMesh_intersection.cxx
new file mode 100644 (file)
index 0000000..8fdf018
--- /dev/null
@@ -0,0 +1,1997 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D
+//
+// 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, 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
+// 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
+//
+// Author : Anthony Geay (CEA/DEN)
+
+#include "MEDCouplingUMesh.hxx"
+#include "MEDCoupling1GTUMesh.hxx"
+#include "CellModel.hxx"
+#include "VolSurfUser.txx"
+#include "InterpolationUtils.hxx"
+#include "PointLocatorAlgos.txx"
+#include "BBTree.txx"
+#include "BBTreeDst.txx"
+#include "DirectedBoundingBox.hxx"
+#include "InterpKernelGeo2DEdgeArcCircle.hxx"
+#include "InterpKernelAutoPtr.hxx"
+#include "InterpKernelGeo2DNode.hxx"
+#include "InterpKernelGeo2DEdgeLin.hxx"
+#include "InterpKernelGeo2DEdgeArcCircle.hxx"
+#include "InterpKernelGeo2DQuadraticPolygon.hxx"
+
+#include <sstream>
+#include <fstream>
+#include <numeric>
+#include <cstring>
+#include <limits>
+#include <list>
+
+using namespace MEDCoupling;
+
+/// @cond INTERNAL
+
+int InternalAddPoint(const INTERP_KERNEL::Edge *e, int id, const double *coo, int startId, int endId, DataArrayDouble& addCoo, int& nodesCnter)
+{
+  if(id!=-1)
+    return id;
+  else
+    {
+      int ret(nodesCnter++);
+      double newPt[2];
+      e->getMiddleOfPoints(coo+2*startId,coo+2*endId,newPt);
+      addCoo.insertAtTheEnd(newPt,newPt+2);
+      return ret;
+    }
+}
+
+int InternalAddPointOriented(const INTERP_KERNEL::Edge *e, int id, const double *coo, int startId, int endId, DataArrayDouble& addCoo, int& nodesCnter)
+{
+  if(id!=-1)
+    return id;
+  else
+    {
+      int ret(nodesCnter++);
+      double newPt[2];
+      e->getMiddleOfPointsOriented(coo+2*startId,coo+2*endId,newPt);
+      addCoo.insertAtTheEnd(newPt,newPt+2);
+      return ret;
+    }
+}
+
+
+void EnterTheResultOf2DCellFirst(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector<int>& middles)
+{
+  int tmp[3];
+  int trueStart(start>=0?start:nbOfEdges+start);
+  tmp[0]=linOrArc?(int)INTERP_KERNEL::NORM_QPOLYG:(int)INTERP_KERNEL::NORM_POLYGON; tmp[1]=connBg[trueStart]; tmp[2]=connBg[stp];
+  newConnOfCell->insertAtTheEnd(tmp,tmp+3);
+  if(linOrArc)
+    {
+      if(stp-start>1)
+        {
+          int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2);
+          InternalAddPointOriented(e,-1,coords,tmp[1],tmp[2],*appendedCoords,tmp2);
+          middles.push_back(tmp3+offset);
+        }
+      else
+        middles.push_back(connBg[trueStart+nbOfEdges]);
+    }
+}
+
+void EnterTheResultOf2DCellMiddle(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector<int>& middles)
+{
+  int tmpSrt(newConnOfCell->back()),tmpEnd(connBg[stp]);
+  newConnOfCell->pushBackSilent(tmpEnd);
+  if(linOrArc)
+    {
+      if(stp-start>1)
+        {
+          int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2);
+          InternalAddPointOriented(e,-1,coords,tmpSrt,tmpEnd,*appendedCoords,tmp2);
+          middles.push_back(tmp3+offset);
+        }
+      else
+        middles.push_back(connBg[start+nbOfEdges]);
+    }
+}
+
+void EnterTheResultOf2DCellEnd(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector<int>& middles)
+{
+  // only the quadratic point to deal with:
+  if(linOrArc)
+    {
+      if(stp-start>1)
+        {
+          int tmpSrt(connBg[start]),tmpEnd(connBg[stp]);
+          int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2);
+          InternalAddPointOriented(e,-1,coords,tmpSrt,tmpEnd,*appendedCoords,tmp2);
+          middles.push_back(tmp3+offset);
+        }
+      else
+        middles.push_back(connBg[start+nbOfEdges]);
+    }
+}
+
+void IKGeo2DInternalMapper2(INTERP_KERNEL::Node *n, const std::map<MCAuto<INTERP_KERNEL::Node>,int>& m, int forbVal0, int forbVal1, std::vector<int>& isect)
+{
+  MCAuto<INTERP_KERNEL::Node> nTmp(n); nTmp->incrRef();
+  std::map<MCAuto<INTERP_KERNEL::Node>,int>::const_iterator it(m.find(nTmp));
+  if(it==m.end())
+    throw INTERP_KERNEL::Exception("Internal error in remapping !");
+  int v((*it).second);
+  if(v==forbVal0 || v==forbVal1)
+    return ;
+  if(std::find(isect.begin(),isect.end(),v)==isect.end())
+    isect.push_back(v);
+}
+
+bool IKGeo2DInternalMapper(const INTERP_KERNEL::ComposedEdge& c, const std::map<MCAuto<INTERP_KERNEL::Node>,int>& m, int forbVal0, int forbVal1, std::vector<int>& isect)
+{
+  int sz(c.size());
+  if(sz<=1)
+    return false;
+  bool presenceOfOn(false);
+  for(int i=0;i<sz;i++)
+    {
+      INTERP_KERNEL::ElementaryEdge *e(c[i]);
+      if(e->getLoc()!=INTERP_KERNEL::FULL_ON_1)
+        continue ;
+      IKGeo2DInternalMapper2(e->getStartNode(),m,forbVal0,forbVal1,isect);
+      IKGeo2DInternalMapper2(e->getEndNode(),m,forbVal0,forbVal1,isect);
+    }
+  return presenceOfOn;
+}
+
+
+namespace MEDCoupling
+{
+
+  INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge2(INTERP_KERNEL::NormalizedCellType typ, const int *bg, const double *coords2D, std::map< MCAuto<INTERP_KERNEL::Node>,int>& m)
+  {
+    INTERP_KERNEL::Edge *ret(0);
+    MCAuto<INTERP_KERNEL::Node> n0(new INTERP_KERNEL::Node(coords2D[2*bg[0]],coords2D[2*bg[0]+1])),n1(new INTERP_KERNEL::Node(coords2D[2*bg[1]],coords2D[2*bg[1]+1]));
+    m[n0]=bg[0]; m[n1]=bg[1];
+    switch(typ)
+    {
+      case INTERP_KERNEL::NORM_SEG2:
+        {
+          ret=new INTERP_KERNEL::EdgeLin(n0,n1);
+          break;
+        }
+      case INTERP_KERNEL::NORM_SEG3:
+        {
+          INTERP_KERNEL::Node *n2(new INTERP_KERNEL::Node(coords2D[2*bg[2]],coords2D[2*bg[2]+1])); m[n2]=bg[2];
+          INTERP_KERNEL::EdgeLin *e1(new INTERP_KERNEL::EdgeLin(n0,n2)),*e2(new INTERP_KERNEL::EdgeLin(n2,n1));
+          INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
+          // is the SEG3 degenerated, and thus can be reduced to a SEG2?
+          bool colinearity(inters.areColinears());
+          delete e1; delete e2;
+          if(colinearity)
+            { ret=new INTERP_KERNEL::EdgeLin(n0,n1); }
+          else
+            { ret=new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1); }
+          break;
+        }
+      default:
+        throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge2 : Expecting a mesh with spaceDim==2 and meshDim==1 !");
+    }
+    return ret;
+  }
+
+  INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge(INTERP_KERNEL::NormalizedCellType typ, std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >& mapp2, const int *bg)
+  {
+    INTERP_KERNEL::Edge *ret=0;
+    switch(typ)
+    {
+      case INTERP_KERNEL::NORM_SEG2:
+        {
+          ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[1]].first);
+          break;
+        }
+      case INTERP_KERNEL::NORM_SEG3:
+        {
+          INTERP_KERNEL::EdgeLin *e1=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[2]].first);
+          INTERP_KERNEL::EdgeLin *e2=new INTERP_KERNEL::EdgeLin(mapp2[bg[2]].first,mapp2[bg[1]].first);
+          INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
+          // is the SEG3 degenerated, and thus can be reduced to a SEG2?
+          bool colinearity=inters.areColinears();
+          delete e1; delete e2;
+          if(colinearity)
+            ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[1]].first);
+          else
+            ret=new INTERP_KERNEL::EdgeArcCircle(mapp2[bg[0]].first,mapp2[bg[2]].first,mapp2[bg[1]].first);
+          mapp2[bg[2]].second=false;
+          break;
+        }
+      default:
+        throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge : Expecting a mesh with spaceDim==2 and meshDim==1 !");
+    }
+    return ret;
+  }
+
+  /*!
+   * This method creates a sub mesh in Geometric2D DS. The sub mesh is composed by the sub set of cells in 'candidates' taken from
+   * the global mesh 'mDesc'.
+   * The input mesh 'mDesc' must be so that mDim==1 and spaceDim==2.
+   * 'mapp' returns a mapping between local numbering in submesh (represented by a Node*) and the global node numbering in 'mDesc'.
+   */
+  INTERP_KERNEL::QuadraticPolygon *MEDCouplingUMeshBuildQPFromMesh(const MEDCouplingUMesh *mDesc, const std::vector<int>& candidates,
+                                                                   std::map<INTERP_KERNEL::Node *,int>& mapp)
+  {
+    mapp.clear();
+    std::map<int, std::pair<INTERP_KERNEL::Node *,bool> > mapp2;//bool is for a flag specifying if node is boundary (true) or only a middle for SEG3.
+    const double *coo=mDesc->getCoords()->getConstPointer();
+    const int *c=mDesc->getNodalConnectivity()->getConstPointer();
+    const int *cI=mDesc->getNodalConnectivityIndex()->getConstPointer();
+    std::set<int> s;
+    for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
+      s.insert(c+cI[*it]+1,c+cI[(*it)+1]);
+    for(std::set<int>::const_iterator it2=s.begin();it2!=s.end();it2++)
+      {
+        INTERP_KERNEL::Node *n=new INTERP_KERNEL::Node(coo[2*(*it2)],coo[2*(*it2)+1]);
+        mapp2[*it2]=std::pair<INTERP_KERNEL::Node *,bool>(n,true);
+      }
+    INTERP_KERNEL::QuadraticPolygon *ret=new INTERP_KERNEL::QuadraticPolygon;
+    for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
+      {
+        INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)c[cI[*it]];
+        ret->pushBack(MEDCouplingUMeshBuildQPFromEdge(typ,mapp2,c+cI[*it]+1));
+      }
+    for(std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >::const_iterator it2=mapp2.begin();it2!=mapp2.end();it2++)
+      {
+        if((*it2).second.second)
+          mapp[(*it2).second.first]=(*it2).first;
+        ((*it2).second.first)->decrRef();
+      }
+    return ret;
+  }
+
+  INTERP_KERNEL::Node *MEDCouplingUMeshBuildQPNode(int nodeId, const double *coo1, int offset1, const double *coo2, int offset2, const std::vector<double>& addCoo)
+  {
+    if(nodeId>=offset2)
+      {
+        int locId=nodeId-offset2;
+        return new INTERP_KERNEL::Node(addCoo[2*locId],addCoo[2*locId+1]);
+      }
+    if(nodeId>=offset1)
+      {
+        int locId=nodeId-offset1;
+        return new INTERP_KERNEL::Node(coo2[2*locId],coo2[2*locId+1]);
+      }
+    return new INTERP_KERNEL::Node(coo1[2*nodeId],coo1[2*nodeId+1]);
+  }
+
+  /**
+   * Construct a mapping between set of Nodes and the standart MEDCoupling connectivity format (c, cI).
+   */
+  void MEDCouplingUMeshBuildQPFromMesh3(const double *coo1, int offset1, const double *coo2, int offset2, const std::vector<double>& addCoo,
+                                        const int *desc1Bg, const int *desc1End, const std::vector<std::vector<int> >& intesctEdges1,
+                                        /*output*/std::map<INTERP_KERNEL::Node *,int>& mapp, std::map<int,INTERP_KERNEL::Node *>& mappRev)
+  {
+    for(const int *desc1=desc1Bg;desc1!=desc1End;desc1++)
+      {
+        int eltId1=abs(*desc1)-1;
+        for(std::vector<int>::const_iterator it1=intesctEdges1[eltId1].begin();it1!=intesctEdges1[eltId1].end();it1++)
+          {
+            std::map<int,INTERP_KERNEL::Node *>::const_iterator it=mappRev.find(*it1);
+            if(it==mappRev.end())
+              {
+                INTERP_KERNEL::Node *node=MEDCouplingUMeshBuildQPNode(*it1,coo1,offset1,coo2,offset2,addCoo);
+                mapp[node]=*it1;
+                mappRev[*it1]=node;
+              }
+          }
+      }
+  }
+}
+
+
+
+/*!
+ * Returns true if a colinearization has been found in the given cell. If false is returned the content pushed in \a newConnOfCell is equal to [ \a connBg , \a connEnd ) .
+ * \a appendedCoords is a DataArrayDouble instance with number of components equal to one (even if the items are pushed by pair).
+ */
+bool MEDCouplingUMesh::Colinearize2DCell(const double *coords, const int *connBg, const int *connEnd, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords)
+{
+  std::size_t sz(std::distance(connBg,connEnd));
+  if(sz<3)//3 because 2+1(for the cell type) and 2 is the minimal number of edges of 2D cell.
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Colinearize2DCell : the input cell has invalid format !");
+  sz--;
+  INTERP_KERNEL::AutoPtr<int> tmpConn(new int[sz]);
+  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)connBg[0]));
+  unsigned nbs(cm.getNumberOfSons2(connBg+1,sz));
+  unsigned nbOfHit(0); // number of fusions operated
+  int posBaseElt(0),posEndElt(0),nbOfTurn(0);
+  const unsigned int maxNbOfHit = cm.isQuadratic() ? nbs-2 : nbs-3;  // a quad cell is authorized to end up with only two edges, a linear one has to keep 3 at least
+  INTERP_KERNEL::NormalizedCellType typeOfSon;
+  std::vector<int> middles;
+  bool ret(false);
+  for(;(nbOfTurn+nbOfHit)<nbs;nbOfTurn++)
+    {
+      cm.fillSonCellNodalConnectivity2(posBaseElt,connBg+1,sz,tmpConn,typeOfSon);
+      std::map<MCAuto<INTERP_KERNEL::Node>,int> m;
+      INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m));
+      posEndElt = posBaseElt+1;
+
+      // Look backward first: are the final edges of the cells colinear with the first ones?
+      // This initializes posBaseElt.
+      if(nbOfTurn==0)
+        {
+          for(unsigned i=1;i<nbs && nbOfHit<maxNbOfHit;i++) // 2nd condition is to avoid ending with a cell wih one single edge
+            {
+              cm.fillSonCellNodalConnectivity2(nbs-i,connBg+1,sz,tmpConn,typeOfSon);
+              INTERP_KERNEL::Edge *eCand(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m));
+              INTERP_KERNEL::EdgeIntersector *eint(INTERP_KERNEL::Edge::BuildIntersectorWith(e,eCand));
+              bool isColinear=eint->areColinears();
+              if(isColinear)
+                {
+                  nbOfHit++;
+                  posBaseElt--;
+                  ret=true;
+                }
+              delete eint;
+              eCand->decrRef();
+              if(!isColinear)
+                break;
+            }
+        }
+      // Now move forward:
+      const unsigned fwdStart = (nbOfTurn == 0 ? 0 : posBaseElt);  // the first element to be inspected going forward
+      for(unsigned j=fwdStart+1;j<nbs && nbOfHit<maxNbOfHit;j++)  // 2nd condition is to avoid ending with a cell wih one single edge
+        {
+          cm.fillSonCellNodalConnectivity2((int)j,connBg+1,sz,tmpConn,typeOfSon); // get edge #j's connectivity
+          INTERP_KERNEL::Edge *eCand(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m));
+          INTERP_KERNEL::EdgeIntersector *eint(INTERP_KERNEL::Edge::BuildIntersectorWith(e,eCand));
+          bool isColinear(eint->areColinears());
+          if(isColinear)
+            {
+              nbOfHit++;
+              posEndElt++;
+              ret=true;
+            }
+          delete eint;
+          eCand->decrRef();
+          if(!isColinear)
+              break;
+        }
+      //push [posBaseElt,posEndElt) in newConnOfCell using e
+      // The if clauses below are (volontary) not mutually exclusive: on a quad cell with 2 edges, the end of the connectivity is also its begining!
+      if(nbOfTurn==0)
+        // at the begining of the connectivity (insert type)
+        EnterTheResultOf2DCellFirst(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles);
+      else if((nbOfHit+nbOfTurn) != (nbs-1))
+        // in the middle
+        EnterTheResultOf2DCellMiddle(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles);
+      if ((nbOfHit+nbOfTurn) == (nbs-1))
+        // at the end (only quad points to deal with)
+        EnterTheResultOf2DCellEnd(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles);
+      posBaseElt=posEndElt;
+      e->decrRef();
+    }
+  if(!middles.empty())
+    newConnOfCell->insertAtTheEnd(middles.begin(),middles.end());
+  return ret;
+}
+
+
+
+bool IsColinearOfACellOf(const std::vector< std::vector<int> >& intersectEdge1, const std::vector<int>& candidates, int start, int stop, int& retVal)
+{
+  if(candidates.empty())
+    return false;
+  for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
+    {
+      const std::vector<int>& pool(intersectEdge1[*it]);
+      int tmp[2]; tmp[0]=start; tmp[1]=stop;
+      if(std::search(pool.begin(),pool.end(),tmp,tmp+2)!=pool.end())
+        {
+          retVal=*it+1;
+          return true;
+        }
+      tmp[0]=stop; tmp[1]=start;
+      if(std::search(pool.begin(),pool.end(),tmp,tmp+2)!=pool.end())
+        {
+          retVal=-*it-1;
+          return true;
+        }
+    }
+  return false;
+}
+
+/*!
+ * This method performs the 2nd step of Partition of 2D mesh.
+ * This method has 4 inputs :
+ *  - a mesh 'm1' with meshDim==1 and a SpaceDim==2
+ *  - a mesh 'm2' with meshDim==1 and a SpaceDim==2
+ *  - subDiv of size 'm2->getNumberOfCells()' that lists for each seg cell in 'm' the splitting node ids randomly sorted.
+ * The aim of this method is to sort the splitting nodes, if any, and to put them in 'intersectEdge' output parameter based on edges of mesh 'm2'
+ * Nodes end up lying consecutively on a cutted edge.
+ * \param m1 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method.
+ * (Only present for its coords in case of 'subDiv' shares some nodes of 'm1')
+ * \param m2 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method.
+ * \param addCoo input parameter with additional nodes linked to intersection of the 2 meshes.
+ * \param[out] intersectEdge the same content as subDiv, but correclty oriented.
+ */
+void MEDCouplingUMesh::BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2,
+                                           const std::vector<double>& addCoo,
+                                           const std::vector< std::vector<int> >& subDiv, std::vector< std::vector<int> >& intersectEdge)
+{
+  int offset1=m1->getNumberOfNodes();
+  int ncell=m2->getNumberOfCells();
+  const int *c=m2->getNodalConnectivity()->begin();
+  const int *cI=m2->getNodalConnectivityIndex()->begin();
+  const double *coo=m2->getCoords()->begin();
+  const double *cooBis=m1->getCoords()->begin();
+  int offset2=offset1+m2->getNumberOfNodes();
+  intersectEdge.resize(ncell);
+  for(int i=0;i<ncell;i++,cI++)
+    {
+      const std::vector<int>& divs=subDiv[i];
+      int nnode=cI[1]-cI[0]-1;
+      std::map<int, std::pair<INTERP_KERNEL::Node *,bool> > mapp2;
+      std::map<INTERP_KERNEL::Node *, int> mapp22;
+      for(int j=0;j<nnode;j++)
+        {
+          INTERP_KERNEL::Node *nn=new INTERP_KERNEL::Node(coo[2*c[(*cI)+j+1]],coo[2*c[(*cI)+j+1]+1]);
+          int nnid=c[(*cI)+j+1];
+          mapp2[nnid]=std::pair<INTERP_KERNEL::Node *,bool>(nn,true);
+          mapp22[nn]=nnid+offset1;
+        }
+      INTERP_KERNEL::Edge *e=MEDCouplingUMeshBuildQPFromEdge((INTERP_KERNEL::NormalizedCellType)c[*cI],mapp2,c+(*cI)+1);
+      for(std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >::const_iterator it=mapp2.begin();it!=mapp2.end();it++)
+        ((*it).second.first)->decrRef();
+      std::vector<INTERP_KERNEL::Node *> addNodes(divs.size());
+      std::map<INTERP_KERNEL::Node *,int> mapp3;
+      for(std::size_t j=0;j<divs.size();j++)
+        {
+          int id=divs[j];
+          INTERP_KERNEL::Node *tmp=0;
+          if(id<offset1)
+            tmp=new INTERP_KERNEL::Node(cooBis[2*id],cooBis[2*id+1]);
+          else if(id<offset2)
+            tmp=new INTERP_KERNEL::Node(coo[2*(id-offset1)],coo[2*(id-offset1)+1]);//if it happens, bad news mesh 'm2' is non conform.
+          else
+            tmp=new INTERP_KERNEL::Node(addCoo[2*(id-offset2)],addCoo[2*(id-offset2)+1]);
+          addNodes[j]=tmp;
+          mapp3[tmp]=id;
+        }
+      e->sortIdsAbs(addNodes,mapp22,mapp3,intersectEdge[i]);
+      for(std::vector<INTERP_KERNEL::Node *>::const_iterator it=addNodes.begin();it!=addNodes.end();it++)
+        (*it)->decrRef();
+      e->decrRef();
+    }
+}
+
+MEDCouplingUMesh *BuildMesh1DCutFrom(const MEDCouplingUMesh *mesh1D, const std::vector< std::vector<int> >& intersectEdge2, const DataArrayDouble *coords1, const std::vector<double>& addCoo, const std::map<int,int>& mergedNodes, const std::vector< std::vector<int> >& colinear2, const std::vector< std::vector<int> >& intersectEdge1,
+                                     MCAuto<DataArrayInt>& idsInRetColinear, MCAuto<DataArrayInt>& idsInMesh1DForIdsInRetColinear)
+{
+  idsInRetColinear=DataArrayInt::New(); idsInRetColinear->alloc(0,1);
+  idsInMesh1DForIdsInRetColinear=DataArrayInt::New(); idsInMesh1DForIdsInRetColinear->alloc(0,1);
+  int nCells(mesh1D->getNumberOfCells());
+  if(nCells!=(int)intersectEdge2.size())
+    throw INTERP_KERNEL::Exception("BuildMesh1DCutFrom : internal error # 1 !");
+  const DataArrayDouble *coo2(mesh1D->getCoords());
+  const int *c(mesh1D->getNodalConnectivity()->begin()),*ci(mesh1D->getNodalConnectivityIndex()->begin());
+  const double *coo2Ptr(coo2->begin());
+  int offset1(coords1->getNumberOfTuples());
+  int offset2(offset1+coo2->getNumberOfTuples());
+  int offset3(offset2+addCoo.size()/2);
+  std::vector<double> addCooQuad;
+  MCAuto<DataArrayInt> cOut(DataArrayInt::New()),ciOut(DataArrayInt::New()); cOut->alloc(0,1); ciOut->alloc(1,1); ciOut->setIJ(0,0,0);
+  int tmp[4],cicnt(0),kk(0);
+  for(int i=0;i<nCells;i++)
+    {
+      std::map<MCAuto<INTERP_KERNEL::Node>,int> m;
+      INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coo2Ptr,m));
+      const std::vector<int>& subEdges(intersectEdge2[i]);
+      int nbSubEdge(subEdges.size()/2);
+      for(int j=0;j<nbSubEdge;j++,kk++)
+        {
+          MCAuto<INTERP_KERNEL::Node> n1(MEDCouplingUMeshBuildQPNode(subEdges[2*j],coords1->begin(),offset1,coo2Ptr,offset2,addCoo)),n2(MEDCouplingUMeshBuildQPNode(subEdges[2*j+1],coords1->begin(),offset1,coo2Ptr,offset2,addCoo));
+          MCAuto<INTERP_KERNEL::Edge> e2(e->buildEdgeLyingOnMe(n1,n2));
+          INTERP_KERNEL::Edge *e2Ptr(e2);
+          std::map<int,int>::const_iterator itm;
+          if(dynamic_cast<INTERP_KERNEL::EdgeArcCircle *>(e2Ptr))
+            {
+              tmp[0]=INTERP_KERNEL::NORM_SEG3;
+              itm=mergedNodes.find(subEdges[2*j]);
+              tmp[1]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j];
+              itm=mergedNodes.find(subEdges[2*j+1]);
+              tmp[2]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j+1];
+              tmp[3]=offset3+(int)addCooQuad.size()/2;
+              double tmp2[2];
+              e2->getBarycenter(tmp2); addCooQuad.insert(addCooQuad.end(),tmp2,tmp2+2);
+              cicnt+=4;
+              cOut->insertAtTheEnd(tmp,tmp+4);
+              ciOut->pushBackSilent(cicnt);
+            }
+          else
+            {
+              tmp[0]=INTERP_KERNEL::NORM_SEG2;
+              itm=mergedNodes.find(subEdges[2*j]);
+              tmp[1]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j];
+              itm=mergedNodes.find(subEdges[2*j+1]);
+              tmp[2]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j+1];
+              cicnt+=3;
+              cOut->insertAtTheEnd(tmp,tmp+3);
+              ciOut->pushBackSilent(cicnt);
+            }
+          int tmp00;
+          if(IsColinearOfACellOf(intersectEdge1,colinear2[i],tmp[1],tmp[2],tmp00))
+            {
+              idsInRetColinear->pushBackSilent(kk);
+              idsInMesh1DForIdsInRetColinear->pushBackSilent(tmp00);
+            }
+        }
+      e->decrRef();
+    }
+  MCAuto<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(mesh1D->getName(),1));
+  ret->setConnectivity(cOut,ciOut,true);
+  MCAuto<DataArrayDouble> arr3(DataArrayDouble::New());
+  arr3->useArray(&addCoo[0],false,C_DEALLOC,(int)addCoo.size()/2,2);
+  MCAuto<DataArrayDouble> arr4(DataArrayDouble::New()); arr4->useArray(&addCooQuad[0],false,C_DEALLOC,(int)addCooQuad.size()/2,2);
+  std::vector<const DataArrayDouble *> coordss(4);
+  coordss[0]=coords1; coordss[1]=mesh1D->getCoords(); coordss[2]=arr3; coordss[3]=arr4;
+  MCAuto<DataArrayDouble> arr(DataArrayDouble::Aggregate(coordss));
+  ret->setCoords(arr);
+  return ret.retn();
+}
+
+MEDCouplingUMesh *BuildRefined2DCellLinear(const DataArrayDouble *coords, const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1)
+{
+  std::vector<int> allEdges;
+  for(const int *it2(descBg);it2!=descEnd;it2++)
+    {
+      const std::vector<int>& edge1(intersectEdge1[std::abs(*it2)-1]);
+      if(*it2>0)
+        allEdges.insert(allEdges.end(),edge1.begin(),edge1.end());
+      else
+        allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend());
+    }
+  std::size_t nb(allEdges.size());
+  if(nb%2!=0)
+    throw INTERP_KERNEL::Exception("BuildRefined2DCellLinear : internal error 1 !");
+  std::size_t nbOfEdgesOf2DCellSplit(nb/2);
+  MCAuto<MEDCouplingUMesh> ret(MEDCouplingUMesh::New("",2));
+  ret->setCoords(coords);
+  ret->allocateCells(1);
+  std::vector<int> connOut(nbOfEdgesOf2DCellSplit);
+  for(std::size_t kk=0;kk<nbOfEdgesOf2DCellSplit;kk++)
+    connOut[kk]=allEdges[2*kk];
+  ret->insertNextCell(INTERP_KERNEL::NORM_POLYGON,connOut.size(),&connOut[0]);
+  return ret.retn();
+}
+
+MEDCouplingUMesh *BuildRefined2DCellQuadratic(const DataArrayDouble *coords, const MEDCouplingUMesh *mesh2D, int cellIdInMesh2D, const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1)
+{
+  const int *c(mesh2D->getNodalConnectivity()->begin()),*ci(mesh2D->getNodalConnectivityIndex()->begin());
+  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[cellIdInMesh2D]]));
+  std::size_t ii(0);
+  unsigned sz(cm.getNumberOfSons2(c+ci[cellIdInMesh2D]+1,ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]-1));
+  if(sz!=std::distance(descBg,descEnd))
+    throw INTERP_KERNEL::Exception("BuildRefined2DCellQuadratic : internal error 1 !");
+  INTERP_KERNEL::AutoPtr<int> tmpPtr(new int[ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]]);
+  std::vector<int> allEdges,centers;
+  const double *coordsPtr(coords->begin());
+  MCAuto<DataArrayDouble> addCoo(DataArrayDouble::New()); addCoo->alloc(0,1);
+  int offset(coords->getNumberOfTuples());
+  for(const int *it2(descBg);it2!=descEnd;it2++,ii++)
+    {
+      INTERP_KERNEL::NormalizedCellType typeOfSon;
+      cm.fillSonCellNodalConnectivity2(ii,c+ci[cellIdInMesh2D]+1,ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]-1,tmpPtr,typeOfSon);
+      const std::vector<int>& edge1(intersectEdge1[std::abs(*it2)-1]);
+      if(*it2>0)
+        allEdges.insert(allEdges.end(),edge1.begin(),edge1.end());
+      else
+        allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend());
+      if(edge1.size()==2)
+        centers.push_back(tmpPtr[2]);//special case where no subsplit of edge -> reuse the original center.
+      else
+        {//the current edge has been subsplit -> create corresponding centers.
+          std::size_t nbOfCentersToAppend(edge1.size()/2);
+          std::map< MCAuto<INTERP_KERNEL::Node>,int> m;
+          MCAuto<INTERP_KERNEL::Edge> ee(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpPtr,coordsPtr,m));
+          std::vector<int>::const_iterator it3(allEdges.end()-edge1.size());
+          for(std::size_t k=0;k<nbOfCentersToAppend;k++)
+            {
+              double tmpp[2];
+              const double *aa(coordsPtr+2*(*it3++));
+              const double *bb(coordsPtr+2*(*it3++));
+              ee->getMiddleOfPoints(aa,bb,tmpp);
+              addCoo->insertAtTheEnd(tmpp,tmpp+2);
+              centers.push_back(offset+k);
+            }
+        }
+    }
+  std::size_t nb(allEdges.size());
+  if(nb%2!=0)
+    throw INTERP_KERNEL::Exception("BuildRefined2DCellQuadratic : internal error 2 !");
+  std::size_t nbOfEdgesOf2DCellSplit(nb/2);
+  MCAuto<MEDCouplingUMesh> ret(MEDCouplingUMesh::New("",2));
+  if(addCoo->empty())
+    ret->setCoords(coords);
+  else
+    {
+      addCoo->rearrange(2);
+      addCoo=DataArrayDouble::Aggregate(coords,addCoo);
+      ret->setCoords(addCoo);
+    }
+  ret->allocateCells(1);
+  std::vector<int> connOut(nbOfEdgesOf2DCellSplit);
+  for(std::size_t kk=0;kk<nbOfEdgesOf2DCellSplit;kk++)
+    connOut[kk]=allEdges[2*kk];
+  connOut.insert(connOut.end(),centers.begin(),centers.end());
+  ret->insertNextCell(INTERP_KERNEL::NORM_QPOLYG,connOut.size(),&connOut[0]);
+  return ret.retn();
+}
+
+/*!
+ * This method creates a refinement of a cell in \a mesh2D. Those cell is defined by descending connectivity and the sorted subdivided nodal connectivity
+ * of those edges.
+ *
+ * \param [in] mesh2D - The origin 2D mesh. \b Warning \b coords are not those of \a mesh2D. But mesh2D->getCoords()==coords[:mesh2D->getNumberOfNodes()]
+ */
+MEDCouplingUMesh *BuildRefined2DCell(const DataArrayDouble *coords, const MEDCouplingUMesh *mesh2D, int cellIdInMesh2D, const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1)
+{
+  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(mesh2D->getTypeOfCell(cellIdInMesh2D)));
+  if(!cm.isQuadratic())
+    return BuildRefined2DCellLinear(coords,descBg,descEnd,intersectEdge1);
+  else
+    return BuildRefined2DCellQuadratic(coords,mesh2D,cellIdInMesh2D,descBg,descEnd,intersectEdge1);
+}
+
+void AddCellInMesh2D(MEDCouplingUMesh *mesh2D, const std::vector<int>& conn, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& edges)
+{
+  bool isQuad(false);
+  for(std::vector< MCAuto<INTERP_KERNEL::Edge> >::const_iterator it=edges.begin();it!=edges.end();it++)
+    {
+      const INTERP_KERNEL::Edge *ee(*it);
+      if(dynamic_cast<const INTERP_KERNEL::EdgeArcCircle *>(ee))
+        isQuad=true;
+    }
+  if(!isQuad)
+    mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,conn.size(),&conn[0]);
+  else
+    {
+      const double *coo(mesh2D->getCoords()->begin());
+      std::size_t sz(conn.size());
+      std::vector<double> addCoo;
+      std::vector<int> conn2(conn);
+      int offset(mesh2D->getNumberOfNodes());
+      for(std::size_t i=0;i<sz;i++)
+        {
+          double tmp[2];
+          edges[(i+1)%sz]->getMiddleOfPoints(coo+2*conn[i],coo+2*conn[(i+1)%sz],tmp);// tony a chier i+1 -> i
+          addCoo.insert(addCoo.end(),tmp,tmp+2);
+          conn2.push_back(offset+(int)i);
+        }
+      mesh2D->getCoords()->rearrange(1);
+      mesh2D->getCoords()->pushBackValsSilent(&addCoo[0],&addCoo[0]+addCoo.size());
+      mesh2D->getCoords()->rearrange(2);
+      mesh2D->insertNextCell(INTERP_KERNEL::NORM_QPOLYG,conn2.size(),&conn2[0]);
+    }
+}
+
+/*!
+ * \b WARNING edges in out1 coming from \a splitMesh1D are \b NOT oriented because only used for equation of curve.
+ *
+ * This method cuts in 2 parts the input 2D cell given using boundaries description (\a edge1Bis and \a edge1BisPtr) using
+ * a set of edges defined in \a splitMesh1D.
+ */
+void BuildMesh2DCutInternal2(const MEDCouplingUMesh *splitMesh1D, const std::vector<int>& edge1Bis, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& edge1BisPtr,
+                             std::vector< std::vector<int> >& out0, std::vector< std::vector< MCAuto<INTERP_KERNEL::Edge> > >& out1)
+{
+  std::size_t nb(edge1Bis.size()/2);
+  std::size_t nbOfEdgesOf2DCellSplit(nb/2);
+  int iEnd(splitMesh1D->getNumberOfCells());
+  if(iEnd==0)
+    throw INTERP_KERNEL::Exception("BuildMesh2DCutInternal2 : internal error ! input 1D mesh must have at least one cell !");
+  std::size_t ii,jj;
+  const int *cSplitPtr(splitMesh1D->getNodalConnectivity()->begin()),*ciSplitPtr(splitMesh1D->getNodalConnectivityIndex()->begin());
+  for(ii=0;ii<nb && edge1Bis[2*ii]!=cSplitPtr[ciSplitPtr[0]+1];ii++);
+  for(jj=ii;jj<nb && edge1Bis[2*jj+1]!=cSplitPtr[ciSplitPtr[iEnd-1]+2];jj++);
+  //
+  if(jj==nb)
+    {//the edges splitMesh1D[iStart:iEnd] does not fully cut the current 2D cell -> single output cell
+      out0.resize(1); out1.resize(1);
+      std::vector<int>& connOut(out0[0]);
+      connOut.resize(nbOfEdgesOf2DCellSplit);
+      std::vector< MCAuto<INTERP_KERNEL::Edge> >& edgesPtr(out1[0]);
+      edgesPtr.resize(nbOfEdgesOf2DCellSplit);
+      for(std::size_t kk=0;kk<nbOfEdgesOf2DCellSplit;kk++)
+        {
+          connOut[kk]=edge1Bis[2*kk];
+          edgesPtr[kk]=edge1BisPtr[2*kk];
+        }
+    }
+  else
+    {
+      // [i,iEnd[ contains the
+      out0.resize(2); out1.resize(2);
+      std::vector<int>& connOutLeft(out0[0]);
+      std::vector<int>& connOutRight(out0[1]);//connOutLeft should end with edge1Bis[2*ii] and connOutRight should end with edge1Bis[2*jj+1]
+      std::vector< MCAuto<INTERP_KERNEL::Edge> >& eleft(out1[0]);
+      std::vector< MCAuto<INTERP_KERNEL::Edge> >& eright(out1[1]);
+      for(std::size_t k=ii;k<jj+1;k++)
+        { connOutLeft.push_back(edge1Bis[2*k+1]); eleft.push_back(edge1BisPtr[2*k+1]); }
+      std::vector< MCAuto<INTERP_KERNEL::Edge> > ees(iEnd);
+      for(int ik=0;ik<iEnd;ik++)
+        {
+          std::map< MCAuto<INTERP_KERNEL::Node>,int> m;
+          MCAuto<INTERP_KERNEL::Edge> ee(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)cSplitPtr[ciSplitPtr[ik]],cSplitPtr+ciSplitPtr[ik]+1,splitMesh1D->getCoords()->begin(),m));
+          ees[ik]=ee;
+        }
+      for(int ik=iEnd-1;ik>=0;ik--)
+        connOutLeft.push_back(cSplitPtr[ciSplitPtr[ik]+1]);
+      for(std::size_t k=jj+1;k<nbOfEdgesOf2DCellSplit+ii;k++)
+        { connOutRight.push_back(edge1Bis[2*k+1]); eright.push_back(edge1BisPtr[2*k+1]); }
+      eleft.insert(eleft.end(),ees.rbegin(),ees.rend());
+      for(int ik=0;ik<iEnd;ik++)
+        connOutRight.push_back(cSplitPtr[ciSplitPtr[ik]+2]);
+      eright.insert(eright.end(),ees.begin(),ees.end());
+    }
+}
+
+struct CellInfo
+{
+public:
+  CellInfo() { }
+  CellInfo(const std::vector<int>& edges, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& edgesPtr);
+public:
+  std::vector<int> _edges;
+  std::vector< MCAuto<INTERP_KERNEL::Edge> > _edges_ptr;
+};
+
+CellInfo::CellInfo(const std::vector<int>& edges, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& edgesPtr)
+{
+  std::size_t nbe(edges.size());
+  std::vector<int> edges2(2*nbe); std::vector< MCAuto<INTERP_KERNEL::Edge> > edgesPtr2(2*nbe);
+  for(std::size_t i=0;i<nbe;i++)
+    {
+      edges2[2*i]=edges[i]; edges2[2*i+1]=edges[(i+1)%nbe];
+      edgesPtr2[2*i]=edgesPtr[(i+1)%nbe]; edgesPtr2[2*i+1]=edgesPtr[(i+1)%nbe];//tony a chier
+    }
+  _edges.resize(4*nbe); _edges_ptr.resize(4*nbe);
+  std::copy(edges2.begin(),edges2.end(),_edges.begin()); std::copy(edges2.begin(),edges2.end(),_edges.begin()+2*nbe);
+  std::copy(edgesPtr2.begin(),edgesPtr2.end(),_edges_ptr.begin()); std::copy(edgesPtr2.begin(),edgesPtr2.end(),_edges_ptr.begin()+2*nbe);
+}
+
+class EdgeInfo
+{
+public:
+  EdgeInfo(int istart, int iend, const MCAuto<MEDCouplingUMesh>& mesh):_istart(istart),_iend(iend),_mesh(mesh),_left(-7),_right(-7) { }
+  EdgeInfo(int istart, int iend, int pos, const MCAuto<INTERP_KERNEL::Edge>& edge):_istart(istart),_iend(iend),_edge(edge),_left(pos),_right(pos+1) { }
+  bool isInMyRange(int pos) const { return pos>=_istart && pos<_iend; }
+  void somethingHappendAt(int pos, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newRight);
+  void feedEdgeInfoAt(double eps, const MEDCouplingUMesh *mesh2D, int offset, int neighbors[2]) const;
+private:
+  int _istart;
+  int _iend;
+  MCAuto<MEDCouplingUMesh> _mesh;
+  MCAuto<INTERP_KERNEL::Edge> _edge;
+  int _left;
+  int _right;
+};
+
+void EdgeInfo::somethingHappendAt(int pos, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newRight)
+{
+  const MEDCouplingUMesh *mesh(_mesh);
+  if(mesh)
+    return ;
+  if(_right<pos)
+    return ;
+  if(_left>pos)
+    { _left++; _right++; return ; }
+  if(_right==pos)
+    {
+      bool isLeft(std::find(newLeft.begin(),newLeft.end(),_edge)!=newLeft.end()),isRight(std::find(newRight.begin(),newRight.end(),_edge)!=newRight.end());
+      if((isLeft && isRight) || (!isLeft && !isRight))
+        throw INTERP_KERNEL::Exception("EdgeInfo::somethingHappendAt : internal error # 1 !");
+      if(isLeft)
+        return ;
+      if(isRight)
+        {
+          _right++;
+          return ;
+        }
+    }
+  if(_left==pos)
+    {
+      bool isLeft(std::find(newLeft.begin(),newLeft.end(),_edge)!=newLeft.end()),isRight(std::find(newRight.begin(),newRight.end(),_edge)!=newRight.end());
+      if((isLeft && isRight) || (!isLeft && !isRight))
+        throw INTERP_KERNEL::Exception("EdgeInfo::somethingHappendAt : internal error # 2 !");
+      if(isLeft)
+        {
+          _right++;
+          return ;
+        }
+      if(isRight)
+        {
+          _left++;
+          _right++;
+          return ;
+        }
+    }
+}
+
+void EdgeInfo::feedEdgeInfoAt(double eps, const MEDCouplingUMesh *mesh2D, int offset, int neighbors[2]) const
+{
+  const MEDCouplingUMesh *mesh(_mesh);
+  if(!mesh)
+    {
+      neighbors[0]=offset+_left; neighbors[1]=offset+_right;
+    }
+  else
+    {// not fully splitting cell case
+      if(mesh2D->getNumberOfCells()==1)
+        {//little optimization. 1 cell no need to find in which cell mesh is !
+          neighbors[0]=offset; neighbors[1]=offset;
+          return;
+        }
+      else
+        {
+          MCAuto<DataArrayDouble> barys(mesh->computeCellCenterOfMass());
+          int cellId(mesh2D->getCellContainingPoint(barys->begin(),eps));
+          if(cellId==-1)
+            throw INTERP_KERNEL::Exception("EdgeInfo::feedEdgeInfoAt : internal error !");
+          neighbors[0]=offset+cellId; neighbors[1]=offset+cellId;
+        }
+    }
+}
+
+class VectorOfCellInfo
+{
+public:
+  VectorOfCellInfo(const std::vector<int>& edges, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& edgesPtr);
+  std::size_t size() const { return _pool.size(); }
+  int getPositionOf(double eps, const MEDCouplingUMesh *mesh) const;
+  void setMeshAt(int pos, const MCAuto<MEDCouplingUMesh>& mesh, int istart, int iend, const MCAuto<MEDCouplingUMesh>& mesh1DInCase, const std::vector< std::vector<int> >& edges, const std::vector< std::vector< MCAuto<INTERP_KERNEL::Edge> > >& edgePtrs);
+  const std::vector<int>& getConnOf(int pos) const { return get(pos)._edges; }
+  const std::vector< MCAuto<INTERP_KERNEL::Edge> >& getEdgePtrOf(int pos) const { return get(pos)._edges_ptr; }
+  MCAuto<MEDCouplingUMesh> getZeMesh() const { return _ze_mesh; }
+  void feedEdgeInfoAt(double eps, int pos, int offset, int neighbors[2]) const;
+private:
+  int getZePosOfEdgeGivenItsGlobalId(int pos) const;
+  void updateEdgeInfo(int pos, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newRight);
+  const CellInfo& get(int pos) const;
+  CellInfo& get(int pos);
+private:
+  std::vector<CellInfo> _pool;
+  MCAuto<MEDCouplingUMesh> _ze_mesh;
+  std::vector<EdgeInfo> _edge_info;
+};
+
+VectorOfCellInfo::VectorOfCellInfo(const std::vector<int>& edges, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& edgesPtr):_pool(1)
+{
+  _pool[0]._edges=edges;
+  _pool[0]._edges_ptr=edgesPtr;
+}
+
+int VectorOfCellInfo::getPositionOf(double eps, const MEDCouplingUMesh *mesh) const
+{
+  if(_pool.empty())
+    throw INTERP_KERNEL::Exception("VectorOfCellSplitter::getPositionOf : empty !");
+  if(_pool.size()==1)
+    return 0;
+  const MEDCouplingUMesh *zeMesh(_ze_mesh);
+  if(!zeMesh)
+    throw INTERP_KERNEL::Exception("VectorOfCellSplitter::getPositionOf : null aggregated mesh !");
+  MCAuto<DataArrayDouble> barys(mesh->computeCellCenterOfMass());
+  return zeMesh->getCellContainingPoint(barys->begin(),eps);
+}
+
+void VectorOfCellInfo::setMeshAt(int pos, const MCAuto<MEDCouplingUMesh>& mesh, int istart, int iend, const MCAuto<MEDCouplingUMesh>& mesh1DInCase, const std::vector< std::vector<int> >& edges, const std::vector< std::vector< MCAuto<INTERP_KERNEL::Edge> > >& edgePtrs)
+{
+  get(pos);//to check pos
+  bool isFast(pos==0 && _pool.size()==1);
+  std::size_t sz(edges.size());
+  // dealing with edges
+  if(sz==1)
+    _edge_info.push_back(EdgeInfo(istart,iend,mesh1DInCase));
+  else
+    _edge_info.push_back(EdgeInfo(istart,iend,pos,edgePtrs[0].back()));
+  //
+  std::vector<CellInfo> pool(_pool.size()-1+sz);
+  for(int i=0;i<pos;i++)
+    pool[i]=_pool[i];
+  for(std::size_t j=0;j<sz;j++)
+    pool[pos+j]=CellInfo(edges[j],edgePtrs[j]);
+  for(int i=pos+1;i<(int)_pool.size();i++)
+    pool[i+sz-1]=_pool[i];
+  _pool=pool;
+  //
+  if(sz==2)
+    updateEdgeInfo(pos,edgePtrs[0],edgePtrs[1]);
+  //
+  if(isFast)
+    {
+      _ze_mesh=mesh;
+      return ;
+    }
+  //
+  std::vector< MCAuto<MEDCouplingUMesh> > ms;
+  if(pos>0)
+    {
+      MCAuto<MEDCouplingUMesh> elt(static_cast<MEDCouplingUMesh *>(_ze_mesh->buildPartOfMySelfSlice(0,pos,true)));
+      ms.push_back(elt);
+    }
+  ms.push_back(mesh);
+  if(pos<_ze_mesh->getNumberOfCells()-1)
+  {
+    MCAuto<MEDCouplingUMesh> elt(static_cast<MEDCouplingUMesh *>(_ze_mesh->buildPartOfMySelfSlice(pos+1,_ze_mesh->getNumberOfCells(),true)));
+    ms.push_back(elt);
+  }
+  std::vector< const MEDCouplingUMesh *> ms2(ms.size());
+  for(std::size_t j=0;j<ms2.size();j++)
+    ms2[j]=ms[j];
+  _ze_mesh=MEDCouplingUMesh::MergeUMeshesOnSameCoords(ms2);
+}
+
+void VectorOfCellInfo::feedEdgeInfoAt(double eps, int pos, int offset, int neighbors[2]) const
+{
+  _edge_info[getZePosOfEdgeGivenItsGlobalId(pos)].feedEdgeInfoAt(eps,_ze_mesh,offset,neighbors);
+}
+
+int VectorOfCellInfo::getZePosOfEdgeGivenItsGlobalId(int pos) const
+{
+  if(pos<0)
+    throw INTERP_KERNEL::Exception("VectorOfCellInfo::getZePosOfEdgeGivenItsGlobalId : invalid id ! Must be >=0 !");
+  int ret(0);
+  for(std::vector<EdgeInfo>::const_iterator it=_edge_info.begin();it!=_edge_info.end();it++,ret++)
+    {
+      if((*it).isInMyRange(pos))
+        return ret;
+    }
+  throw INTERP_KERNEL::Exception("VectorOfCellInfo::getZePosOfEdgeGivenItsGlobalId : invalid id !");
+}
+
+void VectorOfCellInfo::updateEdgeInfo(int pos, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& newRight)
+{
+  get(pos);//to check;
+  if(_edge_info.empty())
+    return ;
+  std::size_t sz(_edge_info.size()-1);
+  for(std::size_t i=0;i<sz;i++)
+    _edge_info[i].somethingHappendAt(pos,newLeft,newRight);
+}
+
+const CellInfo& VectorOfCellInfo::get(int pos) const
+{
+  if(pos<0 || pos>=(int)_pool.size())
+    throw INTERP_KERNEL::Exception("VectorOfCellSplitter::get const : invalid pos !");
+  return _pool[pos];
+}
+
+CellInfo& VectorOfCellInfo::get(int pos)
+{
+  if(pos<0 || pos>=(int)_pool.size())
+    throw INTERP_KERNEL::Exception("VectorOfCellSplitter::get : invalid pos !");
+  return _pool[pos];
+}
+
+/*!
+ * Given :
+ * - a \b closed set of edges ( \a allEdges and \a allEdgesPtr ) that defines the split descending 2D cell.
+ * - \a splitMesh1D a split 2D curve mesh contained into 2D cell defined above.
+ *
+ * This method returns the 2D mesh and feeds \a idsLeftRight using offset.
+ *
+ * Algorithm : \a splitMesh1D is cut into contiguous parts. Each contiguous parts will build incrementally the output 2D cells.
+ *
+ * \param [in] allEdges a list of pairs (beginNode, endNode). Linked with \a allEdgesPtr to get the equation of edge.
+ */
+MEDCouplingUMesh *BuildMesh2DCutInternal(double eps, const MEDCouplingUMesh *splitMesh1D, const std::vector<int>& allEdges, const std::vector< MCAuto<INTERP_KERNEL::Edge> >& allEdgesPtr, int offset,
+                                         MCAuto<DataArrayInt>& idsLeftRight)
+{
+  int nbCellsInSplitMesh1D(splitMesh1D->getNumberOfCells());
+  if(nbCellsInSplitMesh1D==0)
+    throw INTERP_KERNEL::Exception("BuildMesh2DCutInternal : internal error ! input 1D mesh must have at least one cell !");
+  const int *cSplitPtr(splitMesh1D->getNodalConnectivity()->begin()),*ciSplitPtr(splitMesh1D->getNodalConnectivityIndex()->begin());
+  std::size_t nb(allEdges.size()),jj;
+  if(nb%2!=0)
+    throw INTERP_KERNEL::Exception("BuildMesh2DCutFrom : internal error 2 !");
+  std::vector<int> edge1Bis(nb*2);
+  std::vector< MCAuto<INTERP_KERNEL::Edge> > edge1BisPtr(nb*2);
+  std::copy(allEdges.begin(),allEdges.end(),edge1Bis.begin());
+  std::copy(allEdges.begin(),allEdges.end(),edge1Bis.begin()+nb);
+  std::copy(allEdgesPtr.begin(),allEdgesPtr.end(),edge1BisPtr.begin());
+  std::copy(allEdgesPtr.begin(),allEdgesPtr.end(),edge1BisPtr.begin()+nb);
+  //
+  idsLeftRight=DataArrayInt::New(); idsLeftRight->alloc(nbCellsInSplitMesh1D*2); idsLeftRight->fillWithValue(-2); idsLeftRight->rearrange(2);
+  int *idsLeftRightPtr(idsLeftRight->getPointer());
+  VectorOfCellInfo pool(edge1Bis,edge1BisPtr);
+  for(int iStart=0;iStart<nbCellsInSplitMesh1D;)
+    {// split [0:nbCellsInSplitMesh1D) in contiguous parts [iStart:iEnd)
+      int iEnd(iStart);
+      for(;iEnd<nbCellsInSplitMesh1D;)
+        {
+          for(jj=0;jj<nb && edge1Bis[2*jj+1]!=cSplitPtr[ciSplitPtr[iEnd]+2];jj++);
+          if(jj!=nb)
+            break;
+          else
+            iEnd++;
+        }
+      if(iEnd<nbCellsInSplitMesh1D)
+        iEnd++;
+      //
+      MCAuto<MEDCouplingUMesh> partOfSplitMesh1D(static_cast<MEDCouplingUMesh *>(splitMesh1D->buildPartOfMySelfSlice(iStart,iEnd,1,true)));
+      int pos(pool.getPositionOf(eps,partOfSplitMesh1D));
+      //
+      MCAuto<MEDCouplingUMesh>retTmp(MEDCouplingUMesh::New("",2));
+      retTmp->setCoords(splitMesh1D->getCoords());
+      retTmp->allocateCells();
+
+      std::vector< std::vector<int> > out0;
+      std::vector< std::vector< MCAuto<INTERP_KERNEL::Edge> > > out1;
+
+      BuildMesh2DCutInternal2(partOfSplitMesh1D,pool.getConnOf(pos),pool.getEdgePtrOf(pos),out0,out1);
+      for(std::size_t cnt=0;cnt<out0.size();cnt++)
+        AddCellInMesh2D(retTmp,out0[cnt],out1[cnt]);
+      pool.setMeshAt(pos,retTmp,iStart,iEnd,partOfSplitMesh1D,out0,out1);
+      //
+      iStart=iEnd;
+    }
+  for(int mm=0;mm<nbCellsInSplitMesh1D;mm++)
+    pool.feedEdgeInfoAt(eps,mm,offset,idsLeftRightPtr+2*mm);
+  return pool.getZeMesh().retn();
+}
+
+MEDCouplingUMesh *BuildMesh2DCutFrom(double eps, int cellIdInMesh2D, const MEDCouplingUMesh *mesh2DDesc, const MEDCouplingUMesh *splitMesh1D,
+                                     const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1, int offset,
+                                     MCAuto<DataArrayInt>& idsLeftRight)
+{
+  const int *cdescPtr(mesh2DDesc->getNodalConnectivity()->begin()),*cidescPtr(mesh2DDesc->getNodalConnectivityIndex()->begin());
+  //
+  std::vector<int> allEdges;
+  std::vector< MCAuto<INTERP_KERNEL::Edge> > allEdgesPtr; // for each sub edge in splitMesh2D the uncut Edge object of the original mesh2D
+  for(const int *it(descBg);it!=descEnd;it++) // for all edges in the descending connectivity of the 2D mesh in relative Fortran mode
+    {
+      int edgeId(std::abs(*it)-1);
+      std::map< MCAuto<INTERP_KERNEL::Node>,int> m;
+      MCAuto<INTERP_KERNEL::Edge> ee(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)cdescPtr[cidescPtr[edgeId]],cdescPtr+cidescPtr[edgeId]+1,mesh2DDesc->getCoords()->begin(),m));
+      const std::vector<int>& edge1(intersectEdge1[edgeId]);
+      if(*it>0)
+        allEdges.insert(allEdges.end(),edge1.begin(),edge1.end());
+      else
+        allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend());
+      std::size_t sz(edge1.size());
+      for(std::size_t cnt=0;cnt<sz;cnt++)
+        allEdgesPtr.push_back(ee);
+    }
+  //
+  return BuildMesh2DCutInternal(eps,splitMesh1D,allEdges,allEdgesPtr,offset,idsLeftRight);
+}
+
+bool AreEdgeEqual(const double *coo2D, const INTERP_KERNEL::CellModel& typ1, const int *conn1, const INTERP_KERNEL::CellModel& typ2, const int *conn2, double eps)
+{
+  if(!typ1.isQuadratic() && !typ2.isQuadratic())
+    {//easy case comparison not
+      return conn1[0]==conn2[0] && conn1[1]==conn2[1];
+    }
+  else if(typ1.isQuadratic() && typ2.isQuadratic())
+    {
+      bool status0(conn1[0]==conn2[0] && conn1[1]==conn2[1]);
+      if(!status0)
+        return false;
+      if(conn1[2]==conn2[2])
+        return true;
+      const double *a(coo2D+2*conn1[2]),*b(coo2D+2*conn2[2]);
+      double dist(sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])));
+      return dist<eps;
+    }
+  else
+    {//only one is quadratic
+      bool status0(conn1[0]==conn2[0] && conn1[1]==conn2[1]);
+      if(!status0)
+        return false;
+      const double *a(0),*bb(0),*be(0);
+      if(typ1.isQuadratic())
+        {
+          a=coo2D+2*conn1[2]; bb=coo2D+2*conn2[0]; be=coo2D+2*conn2[1];
+        }
+      else
+        {
+          a=coo2D+2*conn2[2]; bb=coo2D+2*conn1[0]; be=coo2D+2*conn1[1];
+        }
+      double b[2]; b[0]=(be[0]+bb[0])/2.; b[1]=(be[1]+bb[1])/2.;
+      double dist(sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])));
+      return dist<eps;
+    }
+}
+
+/*!
+ * This method returns among the cellIds [ \a candidatesIn2DBg , \a candidatesIn2DEnd ) in \a mesh2DSplit those exactly sharing \a cellIdInMesh1DSplitRelative in \a mesh1DSplit.
+ * \a mesh2DSplit and \a mesh1DSplit are expected to share the coordinates array.
+ *
+ * \param [in] cellIdInMesh1DSplitRelative is in Fortran mode using sign to specify direction.
+ */
+int FindRightCandidateAmong(const MEDCouplingUMesh *mesh2DSplit, const int *candidatesIn2DBg, const int *candidatesIn2DEnd, const MEDCouplingUMesh *mesh1DSplit, int cellIdInMesh1DSplitRelative, double eps)
+{
+  if(candidatesIn2DEnd==candidatesIn2DBg)
+    throw INTERP_KERNEL::Exception("FindRightCandidateAmong : internal error 1 !");
+  const double *coo(mesh2DSplit->getCoords()->begin());
+  if(std::distance(candidatesIn2DBg,candidatesIn2DEnd)==1)
+    return *candidatesIn2DBg;
+  int edgeId(std::abs(cellIdInMesh1DSplitRelative)-1);
+  MCAuto<MEDCouplingUMesh> cur1D(static_cast<MEDCouplingUMesh *>(mesh1DSplit->buildPartOfMySelf(&edgeId,&edgeId+1,true)));
+  if(cellIdInMesh1DSplitRelative<0)
+    cur1D->changeOrientationOfCells();
+  const int *c1D(cur1D->getNodalConnectivity()->begin());
+  const INTERP_KERNEL::CellModel& ref1DType(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c1D[0]));
+  for(const int *it=candidatesIn2DBg;it!=candidatesIn2DEnd;it++)
+    {
+      MCAuto<MEDCouplingUMesh> cur2D(static_cast<MEDCouplingUMesh *>(mesh2DSplit->buildPartOfMySelf(it,it+1,true)));
+      const int *c(cur2D->getNodalConnectivity()->begin()),*ci(cur2D->getNodalConnectivityIndex()->begin());
+      const INTERP_KERNEL::CellModel &cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[0]]));
+      unsigned sz(cm.getNumberOfSons2(c+ci[0]+1,ci[1]-ci[0]-1));
+      INTERP_KERNEL::AutoPtr<int> tmpPtr(new int[ci[1]-ci[0]]);
+      for(unsigned it2=0;it2<sz;it2++)
+        {
+          INTERP_KERNEL::NormalizedCellType typeOfSon;
+          cm.fillSonCellNodalConnectivity2(it2,c+ci[0]+1,ci[1]-ci[0]-1,tmpPtr,typeOfSon);
+          const INTERP_KERNEL::CellModel &curCM(INTERP_KERNEL::CellModel::GetCellModel(typeOfSon));
+          if(AreEdgeEqual(coo,ref1DType,c1D+1,curCM,tmpPtr,eps))
+            return *it;
+        }
+    }
+  throw INTERP_KERNEL::Exception("FindRightCandidateAmong : internal error 2 ! Unable to find the edge among split cell !");
+}
+
+/*!
+ * \param [out] intersectEdge1 - for each cell in \a m1Desc returns the result of the split. The result is given using pair of int given resp start and stop.
+ *                               So for all edge \a i in \a m1Desc \a  intersectEdge1[i] is of length 2*n where n is the number of sub edges.
+ *                               And for each j in [1,n) intersect[i][2*(j-1)+1]==intersect[i][2*j].
+ * \param [out] subDiv2 - for each cell in \a m2Desc returns nodes that split it using convention \a m1Desc first, then \a m2Desc, then addCoo
+ * \param [out] colinear2 - for each cell in \a m2Desc returns the edges in \a m1Desc that are colinear to it.
+ * \param [out] addCoo - nodes to be append at the end
+ * \param [out] mergedNodes - gives all pair of nodes of \a m2Desc that have same location than some nodes in \a m1Desc. key is id in \a m2Desc offseted and value is id in \a m1Desc.
+ */
+void MEDCouplingUMesh::Intersect1DMeshes(const MEDCouplingUMesh *m1Desc, const MEDCouplingUMesh *m2Desc, double eps,
+                                         std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& colinear2, std::vector< std::vector<int> >& subDiv2, std::vector<double>& addCoo, std::map<int,int>& mergedNodes)
+{
+  static const int SPACEDIM=2;
+  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
+  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
+  const int *c1(m1Desc->getNodalConnectivity()->begin()),*ci1(m1Desc->getNodalConnectivityIndex()->begin());
+  // Build BB tree of all edges in the tool mesh (second mesh)
+  MCAuto<DataArrayDouble> bbox1Arr(m1Desc->getBoundingBoxForBBTree()),bbox2Arr(m2Desc->getBoundingBoxForBBTree());
+  const double *bbox1(bbox1Arr->begin()),*bbox2(bbox2Arr->begin());
+  int nDescCell1(m1Desc->getNumberOfCells()),nDescCell2(m2Desc->getNumberOfCells());
+  intersectEdge1.resize(nDescCell1);
+  colinear2.resize(nDescCell2);
+  subDiv2.resize(nDescCell2);
+  BBTree<SPACEDIM,int> myTree(bbox2,0,0,m2Desc->getNumberOfCells(),-eps);
+
+  std::vector<int> candidates1(1);
+  int offset1(m1Desc->getNumberOfNodes());
+  int offset2(offset1+m2Desc->getNumberOfNodes());
+  for(int i=0;i<nDescCell1;i++)  // for all edges in the first mesh
+    {
+      std::vector<int> candidates2; // edges of mesh2 candidate for intersection
+      myTree.getIntersectingElems(bbox1+i*2*SPACEDIM,candidates2);
+      if(!candidates2.empty()) // candidates2 holds edges from the second mesh potentially intersecting current edge i in mesh1
+        {
+          std::map<INTERP_KERNEL::Node *,int> map1,map2;
+          // pol2 is not necessarily a closed polygon: just a set of (quadratic) edges (same as candidates2) in the Geometric DS format
+          INTERP_KERNEL::QuadraticPolygon *pol2=MEDCouplingUMeshBuildQPFromMesh(m2Desc,candidates2,map2);
+          candidates1[0]=i;
+          INTERP_KERNEL::QuadraticPolygon *pol1=MEDCouplingUMeshBuildQPFromMesh(m1Desc,candidates1,map1);
+          // This following part is to avoid that some removed nodes (for example due to a merge between pol1 and pol2) are replaced by a newly created one
+          // This trick guarantees that Node * are discriminant (i.e. form a unique identifier)
+          std::set<INTERP_KERNEL::Node *> nodes;
+          pol1->getAllNodes(nodes); pol2->getAllNodes(nodes);
+          std::size_t szz(nodes.size());
+          std::vector< MCAuto<INTERP_KERNEL::Node> > nodesSafe(szz);
+          std::set<INTERP_KERNEL::Node *>::const_iterator itt(nodes.begin());
+          for(std::size_t iii=0;iii<szz;iii++,itt++)
+            { (*itt)->incrRef(); nodesSafe[iii]=*itt; }
+          // end of protection
+          // Performs egde cutting:
+          pol1->splitAbs(*pol2,map1,map2,offset1,offset2,candidates2,intersectEdge1[i],i,colinear2,subDiv2,addCoo,mergedNodes);
+          delete pol2;
+          delete pol1;
+        }
+      else
+        // Copy the edge (take only the two first points, ie discard quadratic point at this stage)
+        intersectEdge1[i].insert(intersectEdge1[i].end(),c1+ci1[i]+1,c1+ci1[i]+3);
+    }
+}
+
+
+/*!
+ * This method is private and is the first step of Partition of 2D mesh (spaceDim==2 and meshDim==2).
+ * It builds the descending connectivity of the two meshes, and then using a binary tree
+ * it computes the edge intersections. This results in new points being created : they're stored in addCoo.
+ * Documentation about parameters  colinear2 and subDiv2 can be found in method QuadraticPolygon::splitAbs().
+ */
+void MEDCouplingUMesh::IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,
+                                                   std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& colinear2, std::vector< std::vector<int> >& subDiv2,
+                                                   MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1,
+                                                   std::vector<double>& addCoo,
+                                                   MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2)
+{
+  // Build desc connectivity
+  desc1=DataArrayInt::New(); descIndx1=DataArrayInt::New(); revDesc1=DataArrayInt::New(); revDescIndx1=DataArrayInt::New();
+  desc2=DataArrayInt::New();
+  descIndx2=DataArrayInt::New();
+  revDesc2=DataArrayInt::New();
+  revDescIndx2=DataArrayInt::New();
+  MCAuto<DataArrayInt> dd1(desc1),dd2(descIndx1),dd3(revDesc1),dd4(revDescIndx1);
+  MCAuto<DataArrayInt> dd5(desc2),dd6(descIndx2),dd7(revDesc2),dd8(revDescIndx2);
+  m1Desc=m1->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1);
+  m2Desc=m2->buildDescendingConnectivity2(desc2,descIndx2,revDesc2,revDescIndx2);
+  MCAuto<MEDCouplingUMesh> dd9(m1Desc),dd10(m2Desc);
+  std::map<int,int> notUsedMap;
+  Intersect1DMeshes(m1Desc,m2Desc,eps,intersectEdge1,colinear2,subDiv2,addCoo,notUsedMap);
+  m1Desc->incrRef(); desc1->incrRef(); descIndx1->incrRef(); revDesc1->incrRef(); revDescIndx1->incrRef();
+  m2Desc->incrRef(); desc2->incrRef(); descIndx2->incrRef(); revDesc2->incrRef(); revDescIndx2->incrRef();
+}
+
+/**
+ * Private. Third step of the partitioning algorithm (Intersect2DMeshes): reconstruct full 2D cells from the
+ * (newly created) nodes corresponding to the edge intersections.
+ * Output params:
+ * @param[out] cr, crI connectivity of the resulting mesh
+ * @param[out] cNb1, cNb2 correspondance arrays giving for the merged mesh the initial cells IDs in m1 / m2
+ * TODO: describe input parameters
+ */
+void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const int *desc1, const int *descIndx1,
+                                                         const std::vector<std::vector<int> >& intesctEdges1, const std::vector< std::vector<int> >& colinear2,
+                                                         const MEDCouplingUMesh *m2, const int *desc2, const int *descIndx2, const std::vector<std::vector<int> >& intesctEdges2,
+                                                         const std::vector<double>& addCoords,
+                                                         std::vector<double>& addCoordsQuadratic, std::vector<int>& cr, std::vector<int>& crI, std::vector<int>& cNb1, std::vector<int>& cNb2)
+{
+  static const int SPACEDIM=2;
+  const double *coo1(m1->getCoords()->begin());
+  const int *conn1(m1->getNodalConnectivity()->begin()),*connI1(m1->getNodalConnectivityIndex()->begin());
+  int offset1(m1->getNumberOfNodes());
+  const double *coo2(m2->getCoords()->begin());
+  const int *conn2(m2->getNodalConnectivity()->begin()),*connI2(m2->getNodalConnectivityIndex()->begin());
+  int offset2(offset1+m2->getNumberOfNodes());
+  int offset3(offset2+((int)addCoords.size())/2);
+  MCAuto<DataArrayDouble> bbox1Arr(m1->getBoundingBoxForBBTree()),bbox2Arr(m2->getBoundingBoxForBBTree());
+  const double *bbox1(bbox1Arr->begin()),*bbox2(bbox2Arr->begin());
+  // Here a BBTree on 2D-cells, not on segments:
+  BBTree<SPACEDIM,int> myTree(bbox2,0,0,m2->getNumberOfCells(),eps);
+  int ncell1(m1->getNumberOfCells());
+  crI.push_back(0);
+  for(int i=0;i<ncell1;i++)
+    {
+      std::vector<int> candidates2;
+      myTree.getIntersectingElems(bbox1+i*2*SPACEDIM,candidates2);
+      std::map<INTERP_KERNEL::Node *,int> mapp;
+      std::map<int,INTERP_KERNEL::Node *> mappRev;
+      INTERP_KERNEL::QuadraticPolygon pol1;
+      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)conn1[connI1[i]];
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
+      // Populate mapp and mappRev with nodes from the current cell (i) from mesh1 - this also builds the Node* objects:
+      MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,/* output */mapp,mappRev);
+      // pol1 is the full cell from mesh2, in QP format, with all the additional intersecting nodes.
+      pol1.buildFromCrudeDataArray(mappRev,cm.isQuadratic(),conn1+connI1[i]+1,coo1,
+          desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1);
+      //
+      std::set<INTERP_KERNEL::Edge *> edges1;// store all edges of pol1 that are NOT consumed by intersect cells. If any after iteration over candidates2 -> a part of pol1 should appear in result
+      std::set<INTERP_KERNEL::Edge *> edgesBoundary2;// store all edges that are on boundary of (pol2 intersect pol1) minus edges on pol1.
+      INTERP_KERNEL::IteratorOnComposedEdge it1(&pol1);
+      for(it1.first();!it1.finished();it1.next())
+        edges1.insert(it1.current()->getPtr());
+      //
+      std::map<int,std::vector<INTERP_KERNEL::ElementaryEdge *> > edgesIn2ForShare; // common edges
+      std::vector<INTERP_KERNEL::QuadraticPolygon> pol2s(candidates2.size());
+      int ii=0;
+      for(std::vector<int>::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++)
+        {
+          INTERP_KERNEL::NormalizedCellType typ2=(INTERP_KERNEL::NormalizedCellType)conn2[connI2[*it2]];
+          const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel(typ2);
+          // Complete mapping with elements coming from the current cell it2 in mesh2:
+          MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,/* output */mapp,mappRev);
+          // pol2 is the new QP in the final merged result.
+          pol2s[ii].buildFromCrudeDataArray2(mappRev,cm2.isQuadratic(),conn2+connI2[*it2]+1,coo2,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,
+              pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2, /* output */ edgesIn2ForShare);
+        }
+      ii=0;
+      for(std::vector<int>::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++)
+        {
+          INTERP_KERNEL::ComposedEdge::InitLocationsWithOther(pol1,pol2s[ii]);
+          pol2s[ii].updateLocOfEdgeFromCrudeDataArray2(desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2);
+          //MEDCouplingUMeshAssignOnLoc(pol1,pol2,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,colinear2);
+          pol1.buildPartitionsAbs(pol2s[ii],edges1,edgesBoundary2,mapp,i,*it2,offset3,addCoordsQuadratic,cr,crI,cNb1,cNb2);
+        }
+      // Deals with remaining (non-consumed) edges from m1: these are the edges that were never touched
+      // by m2 but that we still want to keep in the final result.
+      if(!edges1.empty())
+        {
+          try
+          {
+              INTERP_KERNEL::QuadraticPolygon::ComputeResidual(pol1,edges1,edgesBoundary2,mapp,offset3,i,addCoordsQuadratic,cr,crI,cNb1,cNb2);
+          }
+          catch(INTERP_KERNEL::Exception& e)
+          {
+              std::ostringstream oss; oss << "Error when computing residual of cell #" << i << " in source/m1 mesh ! Maybe the neighbours of this cell in mesh are not well connected !\n" << "The deep reason is the following : " << e.what();
+              throw INTERP_KERNEL::Exception(oss.str());
+          }
+        }
+      for(std::map<int,INTERP_KERNEL::Node *>::const_iterator it=mappRev.begin();it!=mappRev.end();it++)
+        (*it).second->decrRef();
+    }
+}
+
+void InsertNodeInConnIfNecessary(int nodeIdToInsert, std::vector<int>& conn, const double *coords, double eps)
+{
+  std::vector<int>::iterator it(std::find(conn.begin(),conn.end(),nodeIdToInsert));
+  if(it!=conn.end())
+    return ;
+  std::size_t sz(conn.size());
+  std::size_t found(std::numeric_limits<std::size_t>::max());
+  for(std::size_t i=0;i<sz;i++)
+    {
+      int pt0(conn[i]),pt1(conn[(i+1)%sz]);
+      double v1[3]={coords[3*pt1+0]-coords[3*pt0+0],coords[3*pt1+1]-coords[3*pt0+1],coords[3*pt1+2]-coords[3*pt0+2]},v2[3]={coords[3*nodeIdToInsert+0]-coords[3*pt0+0],coords[3*nodeIdToInsert+1]-coords[3*pt0+1],coords[3*nodeIdToInsert+2]-coords[3*pt0+2]};
+      double normm(sqrt(v1[0]*v1[0]+v1[1]*v1[1]+v1[2]*v1[2]));
+      std::transform(v1,v1+3,v1,std::bind2nd(std::multiplies<double>(),1./normm));
+      std::transform(v2,v2+3,v2,std::bind2nd(std::multiplies<double>(),1./normm));
+      double v3[3];
+      v3[0]=v1[1]*v2[2]-v1[2]*v2[1]; v3[1]=v1[2]*v2[0]-v1[0]*v2[2]; v3[2]=v1[0]*v2[1]-v1[1]*v2[0];
+      double normm2(sqrt(v3[0]*v3[0]+v3[1]*v3[1]+v3[2]*v3[2])),dotTest(v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]);
+      if(normm2<eps)
+        if(dotTest>eps && dotTest<1.-eps)
+          {
+            found=i;
+            break;
+          }
+    }
+  if(found==std::numeric_limits<std::size_t>::max())
+    throw INTERP_KERNEL::Exception("InsertNodeInConnIfNecessary : not found point !");
+  conn.insert(conn.begin()+(found+1)%sz,nodeIdToInsert);
+}
+
+void SplitIntoToPart(const std::vector<int>& conn, int pt0, int pt1, std::vector<int>& part0, std::vector<int>& part1)
+{
+  std::size_t sz(conn.size());
+  std::vector<int> *curPart(&part0);
+  for(std::size_t i=0;i<sz;i++)
+    {
+      int nextt(conn[(i+1)%sz]);
+      (*curPart).push_back(nextt);
+      if(nextt==pt0 || nextt==pt1)
+        {
+          if(curPart==&part0)
+            curPart=&part1;
+          else
+            curPart=&part0;
+          (*curPart).push_back(nextt);
+        }
+    }
+}
+
+/*!
+ * this method method splits cur cells 3D Surf in sub cells 3DSurf using the previous subsplit. This method is the last one used to clip.
+ */
+void MEDCouplingUMesh::buildSubCellsFromCut(const std::vector< std::pair<int,int> >& cut3DSurf,
+                                            const int *desc, const int *descIndx, const double *coords, double eps,
+                                            std::vector<std::vector<int> >& res) const
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSubCellsFromCut works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!");
+  const int *nodal3D(_nodal_connec->begin()),*nodalIndx3D(_nodal_connec_index->begin());
+  int nbOfCells(getNumberOfCells());
+  if(nbOfCells!=1)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSubCellsFromCut works only with single cell presently !");
+  for(int i=0;i<nbOfCells;i++)
+    {
+      int offset(descIndx[i]),nbOfFaces(descIndx[i+1]-offset),start(-1),end(-1);
+      for(int j=0;j<nbOfFaces;j++)
+        {
+          const std::pair<int,int>& p=cut3DSurf[desc[offset+j]];
+          const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodal3D[nodalIndx3D[i]]));
+          int sz=nodalIndx3D[i+1]-nodalIndx3D[i]-1;
+          INTERP_KERNEL::AutoPtr<int> tmp(new int[sz]);
+          INTERP_KERNEL::NormalizedCellType cmsId;
+          unsigned nbOfNodesSon(cm.fillSonCellNodalConnectivity2(j,nodal3D+nodalIndx3D[i]+1,sz,tmp,cmsId));
+          std::vector<int> elt((int *)tmp,(int *)tmp+nbOfNodesSon);
+          if(p.first!=-1 && p.second!=-1)
+            {
+              if(p.first!=-2)
+                {
+                  InsertNodeInConnIfNecessary(p.first,elt,coords,eps);
+                  InsertNodeInConnIfNecessary(p.second,elt,coords,eps);
+                  std::vector<int> elt1,elt2;
+                  SplitIntoToPart(elt,p.first,p.second,elt1,elt2);
+                  res.push_back(elt1);
+                  res.push_back(elt2);
+                }
+              else
+                res.push_back(elt);
+            }
+          else
+            res.push_back(elt);
+        }
+    }
+}
+
+/*!
+ * It is the linear part of MEDCouplingUMesh::split2DCells. Here no additionnal nodes will be added in \b this. So coordinates pointer remain unchanged (is not even touch).
+ *
+ * \sa MEDCouplingUMesh::split2DCells
+ */
+void MEDCouplingUMesh::split2DCellsLinear(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI)
+{
+  checkConnectivityFullyDefined();
+  int ncells(getNumberOfCells()),lgthToReach(getNodalConnectivityArrayLen()+subNodesInSeg->getNumberOfTuples());
+  MCAuto<DataArrayInt> c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach);
+  const int *subPtr(subNodesInSeg->begin()),*subIPtr(subNodesInSegI->begin()),*descPtr(desc->begin()),*descIPtr(descI->begin()),*oldConn(getNodalConnectivity()->begin());
+  int *cPtr(c->getPointer()),*ciPtr(getNodalConnectivityIndex()->getPointer());
+  int prevPosOfCi(ciPtr[0]);
+  for(int i=0;i<ncells;i++,ciPtr++,descIPtr++)
+    {
+      int offset(descIPtr[0]),sz(descIPtr[1]-descIPtr[0]),deltaSz(0);
+      *cPtr++=(int)INTERP_KERNEL::NORM_POLYGON; *cPtr++=oldConn[prevPosOfCi+1];
+      for(int j=0;j<sz;j++)
+        {
+          int offset2(subIPtr[descPtr[offset+j]]),sz2(subIPtr[descPtr[offset+j]+1]-subIPtr[descPtr[offset+j]]);
+          for(int k=0;k<sz2;k++)
+            *cPtr++=subPtr[offset2+k];
+          if(j!=sz-1)
+            *cPtr++=oldConn[prevPosOfCi+j+2];
+          deltaSz+=sz2;
+        }
+      prevPosOfCi=ciPtr[1];
+      ciPtr[1]=ciPtr[0]+1+sz+deltaSz;//sz==old nb of nodes because (nb of subedges=nb of nodes for polygons)
+    }
+  if(c->end()!=cPtr)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCellsLinear : Some of edges to be split are orphan !");
+  _nodal_connec->decrRef();
+  _nodal_connec=c.retn(); _types.clear(); _types.insert(INTERP_KERNEL::NORM_POLYGON);
+}
+
+
+/*!
+ * It is the quadratic part of MEDCouplingUMesh::split2DCells. Here some additionnal nodes can be added at the end of coordinates array object.
+ *
+ * \return  int - the number of new nodes created.
+ * \sa MEDCouplingUMesh::split2DCells
+ */
+int MEDCouplingUMesh::split2DCellsQuadratic(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *mid, const DataArrayInt *midI)
+{
+  checkConsistencyLight();
+  int ncells(getNumberOfCells()),lgthToReach(getNodalConnectivityArrayLen()+2*subNodesInSeg->getNumberOfTuples()),nodesCnt(getNumberOfNodes());
+  MCAuto<DataArrayInt> c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach);
+  MCAuto<DataArrayDouble> addCoo(DataArrayDouble::New()); addCoo->alloc(0,1);
+  const int *subPtr(subNodesInSeg->begin()),*subIPtr(subNodesInSegI->begin()),*descPtr(desc->begin()),*descIPtr(descI->begin()),*oldConn(getNodalConnectivity()->begin());
+  const int *midPtr(mid->begin()),*midIPtr(midI->begin());
+  const double *oldCoordsPtr(getCoords()->begin());
+  int *cPtr(c->getPointer()),*ciPtr(getNodalConnectivityIndex()->getPointer());
+  int prevPosOfCi(ciPtr[0]);
+  for(int i=0;i<ncells;i++,ciPtr++,descIPtr++)
+    {
+      int offset(descIPtr[0]),sz(descIPtr[1]-descIPtr[0]),deltaSz(sz);
+      for(int j=0;j<sz;j++)
+        { int sz2(subIPtr[descPtr[offset+j]+1]-subIPtr[descPtr[offset+j]]); deltaSz+=sz2; }
+      *cPtr++=(int)INTERP_KERNEL::NORM_QPOLYG; cPtr[0]=oldConn[prevPosOfCi+1];
+      for(int j=0;j<sz;j++)//loop over subedges of oldConn
+        {
+          int offset2(subIPtr[descPtr[offset+j]]),sz2(subIPtr[descPtr[offset+j]+1]-subIPtr[descPtr[offset+j]]),offset3(midIPtr[descPtr[offset+j]]);
+          if(sz2==0)
+            {
+              if(j<sz-1)
+                cPtr[1]=oldConn[prevPosOfCi+2+j];
+              cPtr[deltaSz]=oldConn[prevPosOfCi+1+j+sz]; cPtr++;
+              continue;
+            }
+          std::vector<INTERP_KERNEL::Node *> ns(3);
+          ns[0]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+j]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+j]+1]);
+          ns[1]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+(1+j)%sz]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+(1+j)%sz]+1]);
+          ns[2]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+sz+j]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+sz+j]+1]);
+          MCAuto<INTERP_KERNEL::Edge> e(INTERP_KERNEL::QuadraticPolygon::BuildArcCircleEdge(ns));
+          for(int k=0;k<sz2;k++)//loop over subsplit of current subedge
+            {
+              cPtr[1]=subPtr[offset2+k];
+              cPtr[deltaSz]=InternalAddPoint(e,midPtr[offset3+k],oldCoordsPtr,cPtr[0],cPtr[1],*addCoo,nodesCnt); cPtr++;
+            }
+          int tmpEnd(oldConn[prevPosOfCi+1+(j+1)%sz]);
+          if(j!=sz-1)
+            { cPtr[1]=tmpEnd; }
+          cPtr[deltaSz]=InternalAddPoint(e,midPtr[offset3+sz2],oldCoordsPtr,cPtr[0],tmpEnd,*addCoo,nodesCnt); cPtr++;
+        }
+      prevPosOfCi=ciPtr[1]; cPtr+=deltaSz;
+      ciPtr[1]=ciPtr[0]+1+2*deltaSz;//sz==old nb of nodes because (nb of subedges=nb of nodes for polygons)
+    }
+  if(c->end()!=cPtr)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCellsQuadratic : Some of edges to be split are orphan !");
+  _nodal_connec->decrRef();
+  _nodal_connec=c.retn(); _types.clear(); _types.insert(INTERP_KERNEL::NORM_QPOLYG);
+  addCoo->rearrange(2);
+  MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(getCoords(),addCoo));//info are copied from getCoords() by using Aggregate
+  setCoords(coo);
+  return addCoo->getNumberOfTuples();
+}
+
+
+/// @endcond
+
+/*!
+ * Partitions the first given 2D mesh using the second given 2D mesh as a tool, and
+ * returns a result mesh constituted by polygons.
+ * Thus the final result contains all nodes from m1 plus new nodes. However it doesn't necessarily contains
+ * all nodes from m2.
+ * The meshes should be in 2D space. In
+ * addition, returns two arrays mapping cells of the result mesh to cells of the input
+ * meshes.
+ *  \param [in] m1 - the first input mesh which is a partitioned object. The mesh must be so that each point in the space covered by \a m1
+ *                      must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes)
+ *  \param [in] m2 - the second input mesh which is a partition tool. The mesh must be so that each point in the space covered by \a m2
+ *                      must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes)
+ *  \param [in] eps - precision used to detect coincident mesh entities.
+ *  \param [out] cellNb1 - a new instance of DataArrayInt holding for each result
+ *         cell an id of the cell of \a m1 it comes from. The caller is to delete
+ *         this array using decrRef() as it is no more needed.
+ *  \param [out] cellNb2 - a new instance of DataArrayInt holding for each result
+ *         cell an id of the cell of \a m2 it comes from. -1 value means that a
+ *         result cell comes from a cell (or part of cell) of \a m1 not overlapped by
+ *         any cell of \a m2. The caller is to delete this array using decrRef() as
+ *         it is no more needed.
+ *  \return MEDCouplingUMesh * - the result 2D mesh which is a new instance of
+ *         MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it
+ *         is no more needed.
+ *  \throw If the coordinates array is not set in any of the meshes.
+ *  \throw If the nodal connectivity of cells is not defined in any of the meshes.
+ *  \throw If any of the meshes is not a 2D mesh in 2D space.
+ *
+ *  \sa conformize2D, mergeNodes
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2,
+                                                      double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2)
+{
+  if(!m1 || !m2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshes : input meshes must be not NULL !");
+  m1->checkFullyDefined();
+  m2->checkFullyDefined();
+  if(m1->getMeshDimension()!=2 || m1->getSpaceDimension()!=2 || m2->getMeshDimension()!=2 || m2->getSpaceDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshes works on umeshes m1 AND m2  with meshdim equal to 2 and spaceDim equal to 2 too!");
+
+  // Step 1: compute all edge intersections (new nodes)
+  std::vector< std::vector<int> > intersectEdge1, colinear2, subDiv2;
+  MEDCouplingUMesh *m1Desc=0,*m2Desc=0; // descending connec. meshes
+  DataArrayInt *desc1=0,*descIndx1=0,*revDesc1=0,*revDescIndx1=0,*desc2=0,*descIndx2=0,*revDesc2=0,*revDescIndx2=0;
+  std::vector<double> addCoo,addCoordsQuadratic;  // coordinates of newly created nodes
+  IntersectDescending2DMeshes(m1,m2,eps,intersectEdge1,colinear2, subDiv2,
+                              m1Desc,desc1,descIndx1,revDesc1,revDescIndx1,
+                              addCoo, m2Desc,desc2,descIndx2,revDesc2,revDescIndx2);
+  revDesc1->decrRef(); revDescIndx1->decrRef(); revDesc2->decrRef(); revDescIndx2->decrRef();
+  MCAuto<DataArrayInt> dd1(desc1),dd2(descIndx1),dd3(desc2),dd4(descIndx2);
+  MCAuto<MEDCouplingUMesh> dd5(m1Desc),dd6(m2Desc);
+
+  // Step 2: re-order newly created nodes according to the ordering found in m2
+  std::vector< std::vector<int> > intersectEdge2;
+  BuildIntersectEdges(m1Desc,m2Desc,addCoo,subDiv2,intersectEdge2);
+  subDiv2.clear(); dd5=0; dd6=0;
+
+  // Step 3:
+  std::vector<int> cr,crI; //no DataArrayInt because interface with Geometric2D
+  std::vector<int> cNb1,cNb2; //no DataArrayInt because interface with Geometric2D
+  BuildIntersecting2DCellsFromEdges(eps,m1,desc1->begin(),descIndx1->begin(),intersectEdge1,colinear2,m2,desc2->begin(),descIndx2->begin(),intersectEdge2,addCoo,
+                                    /* outputs -> */addCoordsQuadratic,cr,crI,cNb1,cNb2);
+
+  // Step 4: Prepare final result:
+  MCAuto<DataArrayDouble> addCooDa(DataArrayDouble::New());
+  addCooDa->alloc((int)(addCoo.size())/2,2);
+  std::copy(addCoo.begin(),addCoo.end(),addCooDa->getPointer());
+  MCAuto<DataArrayDouble> addCoordsQuadraticDa(DataArrayDouble::New());
+  addCoordsQuadraticDa->alloc((int)(addCoordsQuadratic.size())/2,2);
+  std::copy(addCoordsQuadratic.begin(),addCoordsQuadratic.end(),addCoordsQuadraticDa->getPointer());
+  std::vector<const DataArrayDouble *> coordss(4);
+  coordss[0]=m1->getCoords(); coordss[1]=m2->getCoords(); coordss[2]=addCooDa; coordss[3]=addCoordsQuadraticDa;
+  MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coordss));
+  MCAuto<MEDCouplingUMesh> ret(MEDCouplingUMesh::New("Intersect2D",2));
+  MCAuto<DataArrayInt> conn(DataArrayInt::New()); conn->alloc((int)cr.size(),1); std::copy(cr.begin(),cr.end(),conn->getPointer());
+  MCAuto<DataArrayInt> connI(DataArrayInt::New()); connI->alloc((int)crI.size(),1); std::copy(crI.begin(),crI.end(),connI->getPointer());
+  MCAuto<DataArrayInt> c1(DataArrayInt::New()); c1->alloc((int)cNb1.size(),1); std::copy(cNb1.begin(),cNb1.end(),c1->getPointer());
+  MCAuto<DataArrayInt> c2(DataArrayInt::New()); c2->alloc((int)cNb2.size(),1); std::copy(cNb2.begin(),cNb2.end(),c2->getPointer());
+  ret->setConnectivity(conn,connI,true);
+  ret->setCoords(coo);
+  cellNb1=c1.retn(); cellNb2=c2.retn();
+  return ret.retn();
+}
+
+/*!
+ * Partitions the first given 2D mesh using the second given 1D mesh as a tool.
+ * Thus the final result contains the aggregation of nodes of \a mesh2D, then nodes of \a mesh1D, then new nodes that are the result of the intersection
+ * and finaly, in case of quadratic polygon the centers of edges new nodes.
+ * The meshes should be in 2D space. In addition, returns two arrays mapping cells of the resulting mesh to cells of the input.
+ *
+ * \param [in] mesh2D - the 2D mesh (spacedim=meshdim=2) to be intersected using \a mesh1D tool. The mesh must be so that each point in the space covered by \a mesh2D
+ *                      must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes)
+ * \param [in] mesh1D - the 1D mesh (spacedim=2 meshdim=1) the is the tool that will be used to intersect \a mesh2D. \a mesh1D must be ordered consecutively. If it is not the case
+ *                      you can invoke orderConsecutiveCells1D on \a mesh1D.
+ * \param [in] eps - precision used to perform intersections and localization operations.
+ * \param [out] splitMesh2D - the result of the split of \a mesh2D mesh.
+ * \param [out] splitMesh1D - the result of the split of \a mesh1D mesh.
+ * \param [out] cellIdInMesh2D - the array that gives for each cell id \a i in \a splitMesh2D the id in \a mesh2D it comes from.
+ *                               So this array has a number of tuples equal to the number of cells of \a splitMesh2D and a number of component equal to 1.
+ * \param [out] cellIdInMesh1D - the array of pair that gives for each cell id \a i in \a splitMesh1D the cell in \a splitMesh2D on the left for the 1st component
+ *                               and the cell in \a splitMesh2D on the right for the 2nt component. -1 means no cell.
+ *                               So this array has a number of tuples equal to the number of cells of \a splitMesh1D and a number of components equal to 2.
+ *
+ * \sa Intersect2DMeshes, orderConsecutiveCells1D, conformize2D, mergeNodes
+ */
+void MEDCouplingUMesh::Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D, const MEDCouplingUMesh *mesh1D, double eps, MEDCouplingUMesh *&splitMesh2D, MEDCouplingUMesh *&splitMesh1D, DataArrayInt *&cellIdInMesh2D, DataArrayInt *&cellIdInMesh1D)
+{
+  if(!mesh2D || !mesh1D)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshWith1DLine : input meshes must be not NULL !");
+  mesh2D->checkFullyDefined();
+  mesh1D->checkFullyDefined();
+  const std::vector<std::string>& compNames(mesh2D->getCoords()->getInfoOnComponents());
+  if(mesh2D->getMeshDimension()!=2 || mesh2D->getSpaceDimension()!=2 || mesh1D->getMeshDimension()!=1 || mesh1D->getSpaceDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshWith1DLine works with mesh2D with spacedim=meshdim=2 and mesh1D with meshdim=1 spaceDim=2 !");
+  // Step 1: compute all edge intersections (new nodes)
+  std::vector< std::vector<int> > intersectEdge1, colinear2, subDiv2;
+  std::vector<double> addCoo,addCoordsQuadratic;  // coordinates of newly created nodes
+  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
+  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
+  //
+  // Build desc connectivity
+  DataArrayInt *desc1(DataArrayInt::New()),*descIndx1(DataArrayInt::New()),*revDesc1(DataArrayInt::New()),*revDescIndx1(DataArrayInt::New());
+  MCAuto<DataArrayInt> dd1(desc1),dd2(descIndx1),dd3(revDesc1),dd4(revDescIndx1);
+  MCAuto<MEDCouplingUMesh> m1Desc(mesh2D->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1));
+  std::map<int,int> mergedNodes;
+  Intersect1DMeshes(m1Desc,mesh1D,eps,intersectEdge1,colinear2,subDiv2,addCoo,mergedNodes);
+  // use mergeNodes to fix intersectEdge1
+  for(std::vector< std::vector<int> >::iterator it0=intersectEdge1.begin();it0!=intersectEdge1.end();it0++)
+    {
+      std::size_t n((*it0).size()/2);
+      int eltStart((*it0)[0]),eltEnd((*it0)[2*n-1]);
+      std::map<int,int>::const_iterator it1;
+      it1=mergedNodes.find(eltStart);
+      if(it1!=mergedNodes.end())
+        (*it0)[0]=(*it1).second;
+      it1=mergedNodes.find(eltEnd);
+      if(it1!=mergedNodes.end())
+        (*it0)[2*n-1]=(*it1).second;
+    }
+  //
+  MCAuto<DataArrayDouble> addCooDa(DataArrayDouble::New());
+  addCooDa->useArray(&addCoo[0],false,C_DEALLOC,(int)addCoo.size()/2,2);
+  // Step 2: re-order newly created nodes according to the ordering found in m2
+  std::vector< std::vector<int> > intersectEdge2;
+  BuildIntersectEdges(m1Desc,mesh1D,addCoo,subDiv2,intersectEdge2);
+  subDiv2.clear();
+  // Step 3: compute splitMesh1D
+  MCAuto<DataArrayInt> idsInRet1Colinear,idsInDescMesh2DForIdsInRetColinear;
+  MCAuto<DataArrayInt> ret2(DataArrayInt::New()); ret2->alloc(0,1);
+  MCAuto<MEDCouplingUMesh> ret1(BuildMesh1DCutFrom(mesh1D,intersectEdge2,mesh2D->getCoords(),addCoo,mergedNodes,colinear2,intersectEdge1,
+      idsInRet1Colinear,idsInDescMesh2DForIdsInRetColinear));
+  MCAuto<DataArrayInt> ret3(DataArrayInt::New()); ret3->alloc(ret1->getNumberOfCells()*2,1); ret3->fillWithValue(std::numeric_limits<int>::max()); ret3->rearrange(2);
+  MCAuto<DataArrayInt> idsInRet1NotColinear(idsInRet1Colinear->buildComplement(ret1->getNumberOfCells()));
+  // deal with cells in mesh2D that are not cut but only some of their edges are
+  MCAuto<DataArrayInt> idsInDesc2DToBeRefined(idsInDescMesh2DForIdsInRetColinear->deepCopy());
+  idsInDesc2DToBeRefined->abs(); idsInDesc2DToBeRefined->applyLin(1,-1);
+  idsInDesc2DToBeRefined=idsInDesc2DToBeRefined->buildUnique();
+  MCAuto<DataArrayInt> out0s;//ids in mesh2D that are impacted by the fact that some edges of \a mesh1D are part of the edges of those cells
+  if(!idsInDesc2DToBeRefined->empty())
+    {
+      DataArrayInt *out0(0),*outi0(0);
+      MEDCouplingUMesh::ExtractFromIndexedArrays(idsInDesc2DToBeRefined->begin(),idsInDesc2DToBeRefined->end(),dd3,dd4,out0,outi0);
+      MCAuto<DataArrayInt> outi0s(outi0);
+      out0s=out0;
+      out0s=out0s->buildUnique();
+      out0s->sort(true);
+    }
+  //
+  MCAuto<MEDCouplingUMesh> ret1NonCol(static_cast<MEDCouplingUMesh *>(ret1->buildPartOfMySelf(idsInRet1NotColinear->begin(),idsInRet1NotColinear->end())));
+  MCAuto<DataArrayDouble> baryRet1(ret1NonCol->computeCellCenterOfMass());
+  MCAuto<DataArrayInt> elts,eltsIndex;
+  mesh2D->getCellsContainingPoints(baryRet1->begin(),baryRet1->getNumberOfTuples(),eps,elts,eltsIndex);
+  MCAuto<DataArrayInt> eltsIndex2(eltsIndex->deltaShiftIndex());
+  MCAuto<DataArrayInt> eltsIndex3(eltsIndex2->findIdsEqual(1));
+  if(eltsIndex2->count(0)+eltsIndex3->getNumberOfTuples()!=ret1NonCol->getNumberOfCells())
+    throw INTERP_KERNEL::Exception("Intersect2DMeshWith1DLine : internal error 1 !");
+  MCAuto<DataArrayInt> cellsToBeModified(elts->buildUnique());
+  MCAuto<DataArrayInt> untouchedCells(cellsToBeModified->buildComplement(mesh2D->getNumberOfCells()));
+  if((DataArrayInt *)out0s)
+    untouchedCells=untouchedCells->buildSubstraction(out0s);//if some edges in ret1 are colinear to descending mesh of mesh2D remove cells from untouched one
+  std::vector< MCAuto<MEDCouplingUMesh> > outMesh2DSplit;
+  // OK all is ready to insert in ret2 mesh
+  if(!untouchedCells->empty())
+    {// the most easy part, cells in mesh2D not impacted at all
+      outMesh2DSplit.push_back(static_cast<MEDCouplingUMesh *>(mesh2D->buildPartOfMySelf(untouchedCells->begin(),untouchedCells->end())));
+      outMesh2DSplit.back()->setCoords(ret1->getCoords());
+      ret2->pushBackValsSilent(untouchedCells->begin(),untouchedCells->end());
+    }
+  if((DataArrayInt *)out0s)
+    {// here dealing with cells in out0s but not in cellsToBeModified
+      MCAuto<DataArrayInt> fewModifiedCells(out0s->buildSubstraction(cellsToBeModified));
+      const int *rdptr(dd3->begin()),*rdiptr(dd4->begin()),*dptr(dd1->begin()),*diptr(dd2->begin());
+      for(const int *it=fewModifiedCells->begin();it!=fewModifiedCells->end();it++)
+        {
+          outMesh2DSplit.push_back(BuildRefined2DCell(ret1->getCoords(),mesh2D,*it,dptr+diptr[*it],dptr+diptr[*it+1],intersectEdge1));
+          ret1->setCoords(outMesh2DSplit.back()->getCoords());
+        }
+      int offset(ret2->getNumberOfTuples());
+      ret2->pushBackValsSilent(fewModifiedCells->begin(),fewModifiedCells->end());
+      MCAuto<DataArrayInt> partOfRet3(DataArrayInt::New()); partOfRet3->alloc(2*idsInRet1Colinear->getNumberOfTuples(),1);
+      partOfRet3->fillWithValue(std::numeric_limits<int>::max()); partOfRet3->rearrange(2);
+      int kk(0),*ret3ptr(partOfRet3->getPointer());
+      for(const int *it=idsInDescMesh2DForIdsInRetColinear->begin();it!=idsInDescMesh2DForIdsInRetColinear->end();it++,kk++)
+        {
+          int faceId(std::abs(*it)-1);
+          for(const int *it2=rdptr+rdiptr[faceId];it2!=rdptr+rdiptr[faceId+1];it2++)
+            {
+              int tmp(fewModifiedCells->findIdFirstEqual(*it2));
+              if(tmp!=-1)
+                {
+                  if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],-(*it))!=dptr+diptr[*it2+1])
+                    ret3ptr[2*kk]=tmp+offset;
+                  if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],(*it))!=dptr+diptr[*it2+1])
+                    ret3ptr[2*kk+1]=tmp+offset;
+                }
+              else
+                {//the current edge is shared by a 2D cell that will be split just after
+                  if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],-(*it))!=dptr+diptr[*it2+1])
+                    ret3ptr[2*kk]=-(*it2+1);
+                  if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],(*it))!=dptr+diptr[*it2+1])
+                    ret3ptr[2*kk+1]=-(*it2+1);
+                }
+            }
+        }
+      m1Desc->setCoords(ret1->getCoords());
+      ret1NonCol->setCoords(ret1->getCoords());
+      ret3->setPartOfValues3(partOfRet3,idsInRet1Colinear->begin(),idsInRet1Colinear->end(),0,2,1,true);
+      if(!outMesh2DSplit.empty())
+        {
+          DataArrayDouble *da(outMesh2DSplit.back()->getCoords());
+          for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator itt=outMesh2DSplit.begin();itt!=outMesh2DSplit.end();itt++)
+            (*itt)->setCoords(da);
+        }
+    }
+  cellsToBeModified=cellsToBeModified->buildUniqueNotSorted();
+  for(const int *it=cellsToBeModified->begin();it!=cellsToBeModified->end();it++)
+    {
+      MCAuto<DataArrayInt> idsNonColPerCell(elts->findIdsEqual(*it));
+      idsNonColPerCell->transformWithIndArr(eltsIndex3->begin(),eltsIndex3->end());
+      MCAuto<DataArrayInt> idsNonColPerCell2(idsInRet1NotColinear->selectByTupleId(idsNonColPerCell->begin(),idsNonColPerCell->end()));
+      MCAuto<MEDCouplingUMesh> partOfMesh1CuttingCur2DCell(static_cast<MEDCouplingUMesh *>(ret1NonCol->buildPartOfMySelf(idsNonColPerCell->begin(),idsNonColPerCell->end())));
+      MCAuto<DataArrayInt> partOfRet3;
+      MCAuto<MEDCouplingUMesh> splitOfOneCell(BuildMesh2DCutFrom(eps,*it,m1Desc,partOfMesh1CuttingCur2DCell,dd1->begin()+dd2->getIJ(*it,0),dd1->begin()+dd2->getIJ((*it)+1,0),intersectEdge1,ret2->getNumberOfTuples(),partOfRet3));
+      ret3->setPartOfValues3(partOfRet3,idsNonColPerCell2->begin(),idsNonColPerCell2->end(),0,2,1,true);
+      outMesh2DSplit.push_back(splitOfOneCell);
+      for(int i=0;i<splitOfOneCell->getNumberOfCells();i++)
+        ret2->pushBackSilent(*it);
+    }
+  //
+  std::size_t nbOfMeshes(outMesh2DSplit.size());
+  std::vector<const MEDCouplingUMesh *> tmp(nbOfMeshes);
+  for(std::size_t i=0;i<nbOfMeshes;i++)
+    tmp[i]=outMesh2DSplit[i];
+  //
+  ret1->getCoords()->setInfoOnComponents(compNames);
+  MCAuto<MEDCouplingUMesh> ret2D(MEDCouplingUMesh::MergeUMeshesOnSameCoords(tmp));
+  // To finish - filter ret3 - std::numeric_limits<int>::max() -> -1 - negate values must be resolved.
+  ret3->rearrange(1);
+  MCAuto<DataArrayInt> edgesToDealWith(ret3->findIdsStricltyNegative());
+  for(const int *it=edgesToDealWith->begin();it!=edgesToDealWith->end();it++)
+    {
+      int old2DCellId(-ret3->getIJ(*it,0)-1);
+      MCAuto<DataArrayInt> candidates(ret2->findIdsEqual(old2DCellId));
+      ret3->setIJ(*it,0,FindRightCandidateAmong(ret2D,candidates->begin(),candidates->end(),ret1,*it%2==0?-((*it)/2+1):(*it)/2+1,eps));// div by 2 because 2 components natively in ret3
+    }
+  ret3->changeValue(std::numeric_limits<int>::max(),-1);
+  ret3->rearrange(2);
+  //
+  splitMesh1D=ret1.retn();
+  splitMesh2D=ret2D.retn();
+  cellIdInMesh2D=ret2.retn();
+  cellIdInMesh1D=ret3.retn();
+}
+
+/*!
+ * \b WARNING this method is \b potentially \b non \b const (if returned array is empty).
+ * \b WARNING this method lead to have a non geometric type sorted mesh (for MED file users) !
+ * This method performs a conformization of \b this. So if a edge in \a this can be split into entire edges in \a this this method
+ * will suppress such edges to use sub edges in \a this. So this method does not add nodes in \a this if merged edges are both linear (INTERP_KERNEL::NORM_SEG2).
+ * In the other cases new nodes can be created. If any are created, they will be appended at the end of the coordinates object before the invokation of this method.
+ *
+ * Whatever the returned value, this method does not alter the order of cells in \a this neither the orientation of cells.
+ * The modified cells, if any, are systematically declared as NORM_POLYGON or NORM_QPOLYG depending on the initial quadraticness of geometric type.
+ *
+ * This method expects that \b this has a meshDim equal 2 and spaceDim equal to 2 too.
+ * This method expects that all nodes in \a this are not closer than \a eps.
+ * If it is not the case you can invoke MEDCouplingUMesh::mergeNodes before calling this method.
+ *
+ * \param [in] eps the relative error to detect merged edges.
+ * \return DataArrayInt  * - The list of cellIds in \a this that have been subdivided. If empty, nothing changed in \a this (as if it were a const method). The array is a newly allocated array
+ *                           that the user is expected to deal with.
+ *
+ * \throw If \a this is not coherent.
+ * \throw If \a this has not spaceDim equal to 2.
+ * \throw If \a this has not meshDim equal to 2.
+ * \sa MEDCouplingUMesh::mergeNodes, MEDCouplingUMesh::split2DCells
+ */
+DataArrayInt *MEDCouplingUMesh::conformize2D(double eps)
+{
+  static const int SPACEDIM=2;
+  checkConsistencyLight();
+  if(getSpaceDimension()!=2 || getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : This method only works for meshes with spaceDim=2 and meshDim=2 !");
+  MCAuto<DataArrayInt> desc1(DataArrayInt::New()),descIndx1(DataArrayInt::New()),revDesc1(DataArrayInt::New()),revDescIndx1(DataArrayInt::New());
+  MCAuto<MEDCouplingUMesh> mDesc(buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1));
+  const int *c(mDesc->getNodalConnectivity()->begin()),*ci(mDesc->getNodalConnectivityIndex()->begin()),*rd(revDesc1->begin()),*rdi(revDescIndx1->begin());
+  MCAuto<DataArrayDouble> bboxArr(mDesc->getBoundingBoxForBBTree());
+  const double *bbox(bboxArr->begin()),*coords(getCoords()->begin());
+  int nCell(getNumberOfCells()),nDescCell(mDesc->getNumberOfCells());
+  std::vector< std::vector<int> > intersectEdge(nDescCell),overlapEdge(nDescCell);
+  std::vector<double> addCoo;
+  BBTree<SPACEDIM,int> myTree(bbox,0,0,nDescCell,-eps);
+  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
+  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
+  for(int i=0;i<nDescCell;i++)
+    {
+      std::vector<int> candidates;
+      myTree.getIntersectingElems(bbox+i*2*SPACEDIM,candidates);
+      for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
+        if(*it>i)
+          {
+            std::map<MCAuto<INTERP_KERNEL::Node>,int> m;
+            INTERP_KERNEL::Edge *e1(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coords,m)),
+                *e2(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[*it]],c+ci[*it]+1,coords,m));
+            INTERP_KERNEL::MergePoints merge;
+            INTERP_KERNEL::QuadraticPolygon c1,c2;
+            e1->intersectWith(e2,merge,c1,c2);
+            e1->decrRef(); e2->decrRef();
+            if(IKGeo2DInternalMapper(c1,m,c[ci[i]+1],c[ci[i]+2],intersectEdge[i]))
+              overlapEdge[i].push_back(*it);
+            if(IKGeo2DInternalMapper(c2,m,c[ci[*it]+1],c[ci[*it]+2],intersectEdge[*it]))
+              overlapEdge[*it].push_back(i);
+          }
+    }
+  // splitting done. sort intersect point in intersectEdge.
+  std::vector< std::vector<int> > middle(nDescCell);
+  int nbOf2DCellsToBeSplit(0);
+  bool middleNeedsToBeUsed(false);
+  std::vector<bool> cells2DToTreat(nDescCell,false);
+  for(int i=0;i<nDescCell;i++)
+    {
+      std::vector<int>& isect(intersectEdge[i]);
+      int sz((int)isect.size());
+      if(sz>1)
+        {
+          std::map<MCAuto<INTERP_KERNEL::Node>,int> m;
+          INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coords,m));
+          e->sortSubNodesAbs(coords,isect);
+          e->decrRef();
+        }
+      if(sz!=0)
+        {
+          int idx0(rdi[i]),idx1(rdi[i+1]);
+          if(idx1-idx0!=1)
+            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : internal error #0 !");
+          if(!cells2DToTreat[rd[idx0]])
+            {
+              cells2DToTreat[rd[idx0]]=true;
+              nbOf2DCellsToBeSplit++;
+            }
+          // try to reuse at most eventual 'middle' of SEG3
+          std::vector<int>& mid(middle[i]);
+          mid.resize(sz+1,-1);
+          if((INTERP_KERNEL::NormalizedCellType)c[ci[i]]==INTERP_KERNEL::NORM_SEG3)
+            {
+              middleNeedsToBeUsed=true;
+              const std::vector<int>& candidates(overlapEdge[i]);
+              std::vector<int> trueCandidates;
+              for(std::vector<int>::const_iterator itc=candidates.begin();itc!=candidates.end();itc++)
+                if((INTERP_KERNEL::NormalizedCellType)c[ci[*itc]]==INTERP_KERNEL::NORM_SEG3)
+                  trueCandidates.push_back(*itc);
+              int stNode(c[ci[i]+1]),endNode(isect[0]);
+              for(int j=0;j<sz+1;j++)
+                {
+                  for(std::vector<int>::const_iterator itc=trueCandidates.begin();itc!=trueCandidates.end();itc++)
+                    {
+                      int tmpSt(c[ci[*itc]+1]),tmpEnd(c[ci[*itc]+2]);
+                      if((tmpSt==stNode && tmpEnd==endNode) || (tmpSt==endNode && tmpEnd==stNode))
+                        { mid[j]=*itc; break; }
+                    }
+                  stNode=endNode;
+                  endNode=j<sz-1?isect[j+1]:c[ci[i]+2];
+                }
+            }
+        }
+    }
+  MCAuto<DataArrayInt> ret(DataArrayInt::New()),notRet(DataArrayInt::New()); ret->alloc(nbOf2DCellsToBeSplit,1);
+  if(nbOf2DCellsToBeSplit==0)
+    return ret.retn();
+  //
+  int *retPtr(ret->getPointer());
+  for(int i=0;i<nCell;i++)
+    if(cells2DToTreat[i])
+      *retPtr++=i;
+  //
+  MCAuto<DataArrayInt> mSafe,nSafe,oSafe,pSafe,qSafe,rSafe;
+  DataArrayInt *m(0),*n(0),*o(0),*p(0),*q(0),*r(0);
+  MEDCouplingUMesh::ExtractFromIndexedArrays(ret->begin(),ret->end(),desc1,descIndx1,m,n); mSafe=m; nSafe=n;
+  DataArrayInt::PutIntoToSkylineFrmt(intersectEdge,o,p); oSafe=o; pSafe=p;
+  if(middleNeedsToBeUsed)
+    { DataArrayInt::PutIntoToSkylineFrmt(middle,q,r); qSafe=q; rSafe=r; }
+  MCAuto<MEDCouplingUMesh> modif(static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(ret->begin(),ret->end(),true)));
+  int nbOfNodesCreated(modif->split2DCells(mSafe,nSafe,oSafe,pSafe,qSafe,rSafe));
+  setCoords(modif->getCoords());//if nbOfNodesCreated==0 modif and this have the same coordinates pointer so this line has no effect. But for quadratic cases this line is important.
+  setPartOfMySelf(ret->begin(),ret->end(),*modif);
+  {
+    bool areNodesMerged; int newNbOfNodes;
+    if(nbOfNodesCreated!=0)
+      MCAuto<DataArrayInt> tmp(mergeNodes(eps,areNodesMerged,newNbOfNodes));
+  }
+  return ret.retn();
+}
+
+/*!
+ * This non const method works on 2D mesh. This method scans every cell in \a this and look if each edge constituting this cell is not mergeable with neighbors edges of that cell.
+ * If yes, the cell is "repaired" to minimize at most its number of edges. So this method do not change the overall shape of cells in \a this (with eps precision).
+ * This method do not take care of shared edges between cells, so this method can lead to a non conform mesh (\a this). If a conform mesh is required you're expected
+ * to invoke MEDCouplingUMesh::mergeNodes and MEDCouplingUMesh::conformize2D right after this call.
+ * This method works on any 2D geometric types of cell (even static one). If a cell is touched its type becomes dynamic automaticaly. For 2D "repaired" quadratic cells
+ * new nodes for center of merged edges is are systematically created and appended at the end of the previously existing nodes.
+ *
+ * If the returned array is empty it means that nothing has changed in \a this (as if it were a const method). If the array is not empty the connectivity of \a this is modified
+ * using new instance, idem for coordinates.
+ *
+ * If \a this is constituted by only linear 2D cells, this method is close to the computation of the convex hull of each cells in \a this.
+ *
+ * \return DataArrayInt  * - The list of cellIds in \a this that have at least one edge colinearized.
+ *
+ * \throw If \a this is not coherent.
+ * \throw If \a this has not spaceDim equal to 2.
+ * \throw If \a this has not meshDim equal to 2.
+ *
+ * \sa MEDCouplingUMesh::conformize2D, MEDCouplingUMesh::mergeNodes, MEDCouplingUMesh::convexEnvelop2D.
+ */
+DataArrayInt *MEDCouplingUMesh::colinearize2D(double eps)
+{
+  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+  checkConsistencyLight();
+  if(getSpaceDimension()!=2 || getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::colinearize2D : This method only works for meshes with spaceDim=2 and meshDim=2 !");
+  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
+  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
+  int nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
+  const int *cptr(_nodal_connec->begin()),*ciptr(_nodal_connec_index->begin());
+  MCAuto<DataArrayInt> newc(DataArrayInt::New()),newci(DataArrayInt::New()); newci->alloc(nbOfCells+1,1); newc->alloc(0,1); newci->setIJ(0,0,0);
+  MCAuto<DataArrayDouble> appendedCoords(DataArrayDouble::New()); appendedCoords->alloc(0,1);//1 not 2 it is not a bug.
+  const double *coords(_coords->begin());
+  int *newciptr(newci->getPointer());
+  for(int i=0;i<nbOfCells;i++,newciptr++,ciptr++)
+    {
+      if(Colinearize2DCell(coords,cptr+ciptr[0],cptr+ciptr[1],nbOfNodes,newc,appendedCoords))
+        ret->pushBackSilent(i);
+      newciptr[1]=newc->getNumberOfTuples();
+    }
+  //
+  if(ret->empty())
+    return ret.retn();
+  if(!appendedCoords->empty())
+    {
+      appendedCoords->rearrange(2);
+      MCAuto<DataArrayDouble> newCoords(DataArrayDouble::Aggregate(getCoords(),appendedCoords));//treat info on components
+      //non const part
+      setCoords(newCoords);
+    }
+  //non const part
+  setConnectivity(newc,newci,true);
+  return ret.retn();
+}
+
+