Salome HOME
small correction of doc
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingUMesh.cxx
index fa1da10ee484ca79aa18eae9654724ddec6d40e0..be7f6ce87cfb1128d7eb44520792c64f21590281 100644 (file)
@@ -314,8 +314,10 @@ void MEDCouplingUMesh::setMeshDimension(int meshDim)
  *
  *  \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".<br>
  *  \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example".
+ *  \endif
  */
 void MEDCouplingUMesh::allocateCells(int nbOfCells)
 {
@@ -345,8 +347,10 @@ void MEDCouplingUMesh::allocateCells(int nbOfCells)
  *  \param [in] size - number of nodes constituting this cell.
  *  \param [in] nodalConnOfCell - the connectivity of the cell to add.
  * 
+ *  \if ENABLE_EXAMPLES
  *  \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".<br>
  *  \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example".
+ *  \endif
  */
 void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell)
 {
@@ -381,8 +385,10 @@ void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, in
  * Compacts data arrays to release unused memory. This method is to be called after
  * finishing cell insertion using \a this->insertNextCell().
  * 
+ *  \if ENABLE_EXAMPLES
  *  \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".<br>
  *  \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example".
+ *  \endif
  */
 void MEDCouplingUMesh::finishInsertingCells()
 {
@@ -583,8 +589,10 @@ void MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double
  * \throw If the coordinates array is not set.
  * \throw If the nodal connectivity of cells is not defined.
  * 
+ * \if ENABLE_EXAMPLES
  * \ref cpp_mcumesh_getReverseNodalConnectivity "Here is a C++ example".<br>
  * \ref  py_mcumesh_getReverseNodalConnectivity "Here is a Python example".
+ * \endif
  */
 void MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
 {
@@ -715,8 +723,10 @@ private:
  *  \throw If \a desc == NULL || \a descIndx == NULL || \a revDesc == NULL || \a
  *         revDescIndx == NULL.
  * 
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_buildDescendingConnectivity "Here is a C++ example".<br>
  *  \ref  py_mcumesh_buildDescendingConnectivity "Here is a Python example".
+ *  \endif
  * \sa buildDescendingConnectivity2()
  */
 MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const
@@ -784,8 +794,10 @@ MEDCouplingUMesh *MEDCouplingUMesh::explode3DMeshTo1D(DataArrayInt *desc, DataAr
  *  \throw If \a desc == NULL || \a descIndx == NULL || \a revDesc == NULL || \a
  *         revDescIndx == NULL.
  * 
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_buildDescendingConnectivity2 "Here is a C++ example".<br>
  *  \ref  py_mcumesh_buildDescendingConnectivity2 "Here is a Python example".
+ *  \endif
  * \sa buildDescendingConnectivity()
  */
 MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const
@@ -1006,8 +1018,10 @@ struct MEDCouplingAccVisit
  *  \throw If the nodal connectivity of cells is node defined.
  *  \throw If dimension of \a this mesh is not either 2 or 3.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_convertToPolyTypes "Here is a C++ example".<br>
  *  \ref  py_mcumesh_convertToPolyTypes "Here is a Python example".
+ *  \endif
  */
 void MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd)
 {
@@ -1040,10 +1054,8 @@ void MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const i
     }
   else
     {
-      int *connIndex=_nodal_connec_index->getPointer();
-      int connIndexLgth=_nodal_connec_index->getNbOfElems();
-      const int *connOld=_nodal_connec->getConstPointer();
-      int connOldLgth=_nodal_connec->getNbOfElems();
+      int *connIndex(_nodal_connec_index->getPointer());
+      const int *connOld(_nodal_connec->getConstPointer());
       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connNew(DataArrayInt::New()),connNewI(DataArrayInt::New()); connNew->alloc(0,1); connNewI->alloc(1,1); connNewI->setIJ(0,0,0);
       std::vector<bool> toBeDone(nbOfCells,false);
       for(const int *iter=cellIdsToConvertBg;iter!=cellIdsToConvertEnd;iter++)
@@ -1131,8 +1143,10 @@ void MEDCouplingUMesh::convertAllToPoly()
  *  \throw If \a this mesh contains polyhedrons with the valid connectivity.
  *  \throw If \a this mesh contains polyhedrons with odd number of nodes.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".<br>
  *  \ref  py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example".
+ *  \endif
  */
 void MEDCouplingUMesh::convertExtrudedPolyhedra()
 {
@@ -1390,8 +1404,10 @@ void MEDCouplingUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
  *  \throw If the nodal connectivity of cells is not defined.
  *  \throw If the nodal connectivity includes an invalid id.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_getNodeIdsInUse "Here is a C++ example".<br>
  *  \ref  py_mcumesh_getNodeIdsInUse "Here is a Python example".
+ *  \endif
  * \sa computeNodeIdsAlg()
  */
 DataArrayInt *MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
@@ -1514,8 +1530,10 @@ DataArrayInt *MEDCouplingUMesh::computeNbOfFacesPerCell() const
  *  \throw If the nodal connectivity of cells is not defined.
  *  \throw If the nodal connectivity includes an invalid id.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_zipCoordsTraducer "Here is a C++ example".<br>
  *  \ref  py_mcumesh_zipCoordsTraducer "Here is a Python example".
+ *  \endif
  */
 DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer()
 {
@@ -1835,8 +1853,10 @@ void MEDCouplingUMesh::FindCommonCellsAlg(int compType, int startCellId, const D
  *  \return bool - \c true if all cells of \a other mesh are present in the \a this
  *         mesh.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_areCellsIncludedIn "Here is a C++ example".<br>
  *  \ref  py_mcumesh_areCellsIncludedIn "Here is a Python example".
+ *  \endif
  *  \sa checkDeepEquivalOnSameNodesWith()
  *  \sa checkGeoEquivalWith()
  */
@@ -1963,8 +1983,10 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, in
  *  \throw If the nodal connectivity of cells is not defined.
  *  \throw If any cell id in the array \a begin is not valid.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_buildPartOfMySelf "Here is a C++ example".<br>
  *  \ref  py_mcumesh_buildPartOfMySelf "Here is a Python example".
+ *  \endif
  */
 MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const
 {
@@ -2151,8 +2173,10 @@ void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int
  *  \throw If the nodal connectivity of cells is not defined.
  *  \throw If any node id in \a begin is not valid.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_buildFacePartOfMySelfNode "Here is a C++ example".<br>
  *  \ref  py_mcumesh_buildFacePartOfMySelfNode "Here is a Python example".
+ *  \endif
  */
 MEDCouplingPointSet *MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const
 {
@@ -2174,8 +2198,10 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *begi
  *  \throw If the coordinates array is not set.
  *  \throw If the nodal connectivity of cells is not defined.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_buildBoundaryMesh "Here is a C++ example".<br>
  *  \ref  py_mcumesh_buildBoundaryMesh "Here is a Python example".
+ *  \endif
  */
 MEDCouplingPointSet *MEDCouplingUMesh::buildBoundaryMesh(bool keepCoords) const
 {
@@ -2326,8 +2352,10 @@ MEDCouplingUMesh *MEDCouplingUMesh::computeSkin() const
  *  \throw If the coordinates array is not set.
  *  \throw If the nodal connectivity of cells is node defined.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_findBoundaryNodes "Here is a C++ example".<br>
  *  \ref  py_mcumesh_findBoundaryNodes "Here is a Python example".
+ *  \endif
  */
 DataArrayInt *MEDCouplingUMesh::findBoundaryNodes() const
 {
@@ -2429,8 +2457,10 @@ void MEDCouplingUMesh::duplicateNodes(const int *nodeIdsToDuplicateBg, const int
  *         See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
  *  \throw If the nodal connectivity of cells is not defined.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_renumberNodesInConn "Here is a C++ example".<br>
  *  \ref  py_mcumesh_renumberNodesInConn "Here is a Python example".
+ *  \endif
  */
 void MEDCouplingUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
 {
@@ -2585,8 +2615,10 @@ void MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check)
  *  \throw If the coordinates array is not set.
  *  \throw If the nodal connectivity of cells is not defined.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_getCellsInBoundingBox "Here is a C++ example".<br>
  *  \ref  py_mcumesh_getCellsInBoundingBox "Here is a Python example".
+ *  \endif
  */
 DataArrayInt *MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
 {
@@ -3301,8 +3333,10 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const
  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
  *          delete this array using decrRef() as it is no more needed.
  * 
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_getPartMeasureField "Here is a C++ example".<br>
  *  \ref  py_mcumesh_getPartMeasureField "Here is a Python example".
+ *  \endif
  *  \sa getMeasureField()
  */
 DataArrayDouble *MEDCouplingUMesh::getPartMeasureField(bool isAbs, const int *begin, const int *end) const
@@ -3470,8 +3504,10 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const
  *  \throw If the mesh and space dimension is not as specified above.
  *  \sa buildOrthogonalField()
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_buildPartOrthogonalField "Here is a C++ example".<br>
  *  \ref  py_mcumesh_buildPartOrthogonalField "Here is a Python example".
+ *  \endif
  */
 MEDCouplingFieldDouble *MEDCouplingUMesh::buildPartOrthogonalField(const int *begin, const int *end) const
 {
@@ -4062,8 +4098,10 @@ int MEDCouplingUMesh::getCellContainingPoint(const double *pos, double eps) cons
  *  \throw If the coordinates array is not set.
  *  \throw If \a this->getMeshDimension() != \a this->getSpaceDimension().
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_getCellsContainingPoint "Here is a C++ example".<br>
  *  \ref  py_mcumesh_getCellsContainingPoint "Here is a Python example".
+ *  \endif
  */
 void MEDCouplingUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
 {
@@ -4092,6 +4130,41 @@ namespace ParaMEDMEM
     INTERP_KERNEL::NormalizedCellType getTypeOfElement(int) const { return (INTERP_KERNEL::NormalizedCellType)0; }
     // end
   };
+  
+  /*!
+   * Warning the nodes in \a m should be decrRefed ! To avoid that Node * pointer be replaced by another instance.
+   */
+  INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge2(INTERP_KERNEL::NormalizedCellType typ, const int *bg, const double *coords2D, std::map<INTERP_KERNEL::Node *,int>& m)
+  {
+    INTERP_KERNEL::Edge *ret=0;
+    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)
   {
@@ -4288,8 +4361,10 @@ void MEDCouplingUMesh::getCellsContainingPointsAlg(const double *coords, const d
  *  \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,
                                                 MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& elts, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& eltsIndex) const
@@ -4383,6 +4458,7 @@ void MEDCouplingUMesh::checkButterflyCells(std::vector<int>& cells, double eps)
  * its connectivity will remain unchanged. If the computation leads to a modification of nodal connectivity of a cell its geometric type will be modified to INTERP_KERNEL::NORM_POLYGON.
  *
  * \return a newly allocated array containing cellIds that have been modified if any. If no cells have been impacted by this method NULL is returned.
+ * \sa MEDCouplingUMesh::colinearize2D
  */
 DataArrayInt *MEDCouplingUMesh::convexEnvelop2D()
 {
@@ -5713,8 +5789,10 @@ void MEDCouplingUMesh::convertDegeneratedCells()
  *  \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
 {
@@ -5747,8 +5825,10 @@ void MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool po
  *  \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::orientCorrectly2DCells(const double *vec, bool polyOnly)
 {
@@ -5801,8 +5881,10 @@ void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly)
  *  \throw If the coordinates array is not set.
  *  \throw If the nodal connectivity of cells is not defined.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".<br>
  *  \ref  py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example".
+ *  \endif
  */
 void MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector<int>& cells) const
 {
@@ -5832,8 +5914,10 @@ void MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector<int>& cell
  *  \throw If the nodal connectivity of cells is not defined.
  *  \throw If the reparation fails.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".<br>
  *  \ref  py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example".
+ *  \endif
  * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells
  */
 void MEDCouplingUMesh::orientCorrectlyPolyhedrons()
@@ -5877,8 +5961,10 @@ void MEDCouplingUMesh::orientCorrectlyPolyhedrons()
  *  \throw If the coordinates array is not set.
  *  \throw If the nodal connectivity of cells is not defined.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_findAndCorrectBadOriented3DExtrudedCells "Here is a C++ example".<br>
  *  \ref  py_mcumesh_findAndCorrectBadOriented3DExtrudedCells "Here is a Python example".
+ *  \endif
  * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells
  */
 DataArrayInt *MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells()
@@ -6362,8 +6448,8 @@ DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTreeFast() const
 DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic(double arcDetEps) const
 {
   checkFullyDefined();
-  int spaceDim(getSpaceDimension()),mDim(getMeshDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
-  if(spaceDim!=2 || spaceDim!=2)
+  int spaceDim(getSpaceDimension()),mDim(getMeshDimension()),nbOfCells(getNumberOfCells());
+  if(spaceDim!=2 || mDim!=2)
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic : This method should be applied on mesh with mesh dimension equal to 2 and space dimension also equal to 2!");
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
   double *bbox(ret->getPointer());
@@ -6407,8 +6493,8 @@ DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic(double arc
 DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic(double arcDetEps) const
 {
   checkFullyDefined();
-  int spaceDim(getSpaceDimension()),mDim(getMeshDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
-  if(spaceDim!=2 || spaceDim!=2)
+  int spaceDim(getSpaceDimension()),mDim(getMeshDimension()),nbOfCells(getNumberOfCells());
+  if(spaceDim!=2 || mDim!=1)
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic : This method should be applied on mesh with mesh dimension equal to 1 and space dimension also equal to 2!");
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
   double *bbox(ret->getPointer());
@@ -7362,8 +7448,10 @@ DataArrayDouble *MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell() const
  *  \throw If the coordinates array is not set.
  *  \throw If the nodal connectivity of cells is not defined.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcumesh_getPartBarycenterAndOwner "Here is a C++ example".<br>
  *  \ref  py_mcumesh_getPartBarycenterAndOwner "Here is a Python example".
+ *  \endif
  */
 DataArrayDouble *MEDCouplingUMesh::getPartBarycenterAndOwner(const int *begin, const int *end) const
 {
@@ -8254,34 +8342,20 @@ void MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, c
     }
 }
 
-/*!
- * This method makes the assumption spacedimension == meshdimension == 2.
- * This method works only for linear cells.
- * 
- * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYGON in pos#0)
- */
-DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const
+DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshLinear(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const
 {
-  if(getMeshDimension()!=2 || getSpaceDimension()!=2)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : meshdimension, spacedimension must be equal to 2 !");
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=computeSkin();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=m->zipCoordsTraducer();
-  int nbOfNodesExpected=m->getNumberOfNodes();
-  if(m->getNumberOfCells()!=nbOfNodesExpected)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : the mesh 2D in input appears to be not in a single part or a quadratic 2D mesh !");
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(m->getNumberOfNodes());
-  const int *n2oPtr=n2o->getConstPointer();
+  int nbOfNodesExpected(skin->getNumberOfNodes());
+  const int *n2oPtr(n2o->getConstPointer());
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New());
-  m->getReverseNodalConnectivity(revNodal,revNodalI);
-  const int *revNodalPtr=revNodal->getConstPointer(),*revNodalIPtr=revNodalI->getConstPointer();
-  const int *nodalPtr=m->getNodalConnectivity()->getConstPointer();
-  const int *nodalIPtr=m->getNodalConnectivityIndex()->getConstPointer();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodesExpected+1,1);
-  int *work=ret->getPointer();  *work++=INTERP_KERNEL::NORM_POLYGON;
+  skin->getReverseNodalConnectivity(revNodal,revNodalI);
+  const int *revNodalPtr(revNodal->getConstPointer()),*revNodalIPtr(revNodalI->getConstPointer());
+  const int *nodalPtr(skin->getNodalConnectivity()->getConstPointer());
+  const int *nodalIPtr(skin->getNodalConnectivityIndex()->getConstPointer());
+  MEDCouplingAutoRefCountObjectPtr<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;
-  int prevNode=nodalPtr[nodalIPtr[0]+1];
+  int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]);
   *work++=n2oPtr[prevNode];
   for(int i=1;i<nbOfNodesExpected;i++)
     {
@@ -8291,7 +8365,7 @@ DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const
           conn.erase(prevNode);
           if(conn.size()==1)
             {
-              int curNode=*(conn.begin());
+              int curNode(*(conn.begin()));
               *work++=n2oPtr[curNode];
               std::set<int> shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]);
               shar.erase(prevCell);
@@ -8301,17 +8375,89 @@ DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const
                   prevNode=curNode;
                 }
               else
-                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : presence of unexpected 2 !");
+                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->getConstPointer());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New());
+  skin->getReverseNodalConnectivity(revNodal,revNodalI);
+  const int *revNodalPtr(revNodal->getConstPointer()),*revNodalIPtr(revNodalI->getConstPointer());
+  const int *nodalPtr(skin->getNodalConnectivity()->getConstPointer());
+  const int *nodalIPtr(skin->getNodalConnectivityIndex()->getConstPointer());
+  MEDCouplingAutoRefCountObjectPtr<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::buildUnionOf2DMesh : presence of unexpected 1 !");
+            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 1 !");
         }
       else
-        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : presence of unexpected cell !");
+        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected cell !");
     }
   return ret.retn();
 }
 
+/*!
+ * This method makes the assumption spacedimension == meshdimension == 2.
+ * This method works only for linear cells.
+ * 
+ * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYGON in pos#0)
+ */
+DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const
+{
+  if(getMeshDimension()!=2 || getSpaceDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : meshdimension, spacedimension must be equal to 2 !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> skin(computeSkin());
+  int oldNbOfNodes(skin->getNumberOfNodes());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n(skin->zipCoordsTraducer());
+  int nbOfNodesExpected(skin->getNumberOfNodes());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o(o2n->invertArrayO2N2N2O(oldNbOfNodes));
+  int nbCells(skin->getNumberOfCells());
+  if(nbCells==nbOfNodesExpected)
+    return buildUnionOf2DMeshLinear(skin,n2o);
+  else if(2*nbCells==nbOfNodesExpected)
+    return buildUnionOf2DMeshQuadratic(skin,n2o);
+  else
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : the mesh 2D in input appears to be not in a single part of a 2D mesh !");
+}
+
 /*!
  * This method makes the assumption spacedimension == meshdimension == 3.
  * This method works only for linear cells.
@@ -8409,7 +8555,7 @@ void MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData
           w4=std::copy(c.begin(),c.end(),w4);
         }
     }
-  types->transformWithIndArr(PARAMEDMEM2VTKTYPETRADUCER,PARAMEDMEM2VTKTYPETRADUCER+INTERP_KERNEL::NORM_MAXTYPE);
+  types->transformWithIndArr(PARAMEDMEM2VTKTYPETRADUCER,PARAMEDMEM2VTKTYPETRADUCER+INTERP_KERNEL::NORM_MAXTYPE+1);
   types->writeVTK(ofs,8,"UInt8","types",byteData);
   offsets->writeVTK(ofs,8,"Int32","offsets",byteData);
   if(szFaceOffsets!=0)
@@ -8642,6 +8788,266 @@ void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCo
     }
 }
 
+void IKGeo2DInternalMapper2(INTERP_KERNEL::Node *n, const std::map<INTERP_KERNEL::Node *,int>& m, int forbVal0, int forbVal1, std::vector<int>& isect)
+{
+  std::map<INTERP_KERNEL::Node *,int>::const_iterator it(m.find(n));
+  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<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;
+}
+
+/**
+ * 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 index storage mode.
+ * To do the work this method can optionnaly 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;
+  checkCoherency();
+  if(getSpaceDimension()!=2 || getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : This method only works for meshes with spaceDim=2 and meshDim=2 !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1(DataArrayInt::New()),descIndx1(DataArrayInt::New()),revDesc1(DataArrayInt::New()),revDescIndx1(DataArrayInt::New());
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc(buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1));
+  const int *c(mDesc->getNodalConnectivity()->getConstPointer()),*ci(mDesc->getNodalConnectivityIndex()->getConstPointer()),*rd(revDesc1->getConstPointer()),*rdi(revDescIndx1->getConstPointer());
+  MEDCouplingAutoRefCountObjectPtr<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<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);
+            for(std::map<INTERP_KERNEL::Node *,int>::const_iterator it2=m.begin();it2!=m.end();it2++)
+              (*it2).first->decrRef();
+          }
+    }
+  // 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<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();
+          for(std::map<INTERP_KERNEL::Node *,int>::const_iterator it2=m.begin();it2!=m.end();it2++)
+            (*it2).first->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];
+                }
+            }
+        }
+    }
+  MEDCouplingAutoRefCountObjectPtr<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;
+  //
+  MEDCouplingAutoRefCountObjectPtr<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; }
+  MEDCouplingAutoRefCountObjectPtr<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)
+      MEDCouplingAutoRefCountObjectPtr<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)
+{
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+  checkCoherency();
+  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());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newc(DataArrayInt::New()),newci(DataArrayInt::New()); newci->alloc(nbOfCells+1,1); newc->alloc(0,1); newci->setIJ(0,0,0);
+  MEDCouplingAutoRefCountObjectPtr<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);
+      MEDCouplingAutoRefCountObjectPtr<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();
+}
+
 /*!
  * 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
@@ -9715,6 +10121,252 @@ 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(getMeshLength()+subNodesInSeg->getNumberOfTuples());
+  MEDCouplingAutoRefCountObjectPtr<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;
+    }
+}
+
+/// @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);
+          InternalAddPoint(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);
+          InternalAddPoint(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)
+{
+  if(linOrArc)
+    {
+      if(stp-start>1)
+        {
+          int tmpSrt(connBg[start]),tmpEnd(connBg[stp]);
+          int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2);
+          InternalAddPoint(e,-1,coords,tmpSrt,tmpEnd,*appendedCoords,tmp2);
+          middles.push_back(tmp3+offset);
+        }
+      else
+        middles.push_back(connBg[start+nbOfEdges]);
+    }
+}
+
+/// @cond INTERNAL
+
+/*!
+ * 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)),nbOfHit(0);
+  int posBaseElt(0),posEndElt(0),nbOfTurn(0);
+  INTERP_KERNEL::NormalizedCellType typeOfSon;
+  std::vector<int> middles;
+  bool ret(false);
+  for(;nbOfHit<nbs;nbOfTurn++)
+    {
+      cm.fillSonCellNodalConnectivity2(posBaseElt,connBg+1,sz,tmpConn,typeOfSon);
+      std::map<INTERP_KERNEL::Node *,int> m;
+      INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m));
+      posEndElt++;
+      nbOfHit++;
+      unsigned endI(nbs-nbOfHit);
+      for(unsigned i=0;i<endI;i++)
+        {
+          cm.fillSonCellNodalConnectivity2(posBaseElt+(int)i+1,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++;
+              posEndElt++;
+              ret=true;
+            }
+          delete eint;
+          eCand->decrRef();
+          if(!isColinear)
+            {
+              if(nbOfTurn==0)
+                {//look if the first edge of cell is not colinear with last edges in this case the start of nodal connectivity is shifted back
+                  unsigned endII(nbs-nbOfHit-1);//warning nbOfHit can be modified, so put end condition in a variable.
+                  for(unsigned ii=0;ii<endII;ii++)
+                    {
+                      cm.fillSonCellNodalConnectivity2(nbs-ii-1,connBg+1,sz,tmpConn,typeOfSon);
+                      eCand=MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m);
+                      eint=INTERP_KERNEL::Edge::BuildIntersectorWith(e,eCand);
+                      isColinear=eint->areColinears();
+                      if(isColinear)
+                        {
+                          nbOfHit++;
+                          posBaseElt--;
+                          ret=true;
+                        }
+                      delete eint;
+                      eCand->decrRef();
+                    }
+                }
+              break;
+            }
+        }
+      //push [posBaseElt,posEndElt) in newConnOfCell using e
+      if(nbOfTurn==0)
+        EnterTheResultOf2DCellFirst(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles);
+      else if(nbOfHit!=nbs)
+        EnterTheResultOf2DCellMiddle(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles);
+      else
+        EnterTheResultOf2DCellEnd(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles);
+      posBaseElt=posEndElt;
+      for(std::map<INTERP_KERNEL::Node *,int>::const_iterator it=m.begin();it!=m.end();it++)
+        (*it).first->decrRef();
+      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)
+{
+  checkCoherency();
+  int ncells(getNumberOfCells()),lgthToReach(getMeshLength()+2*subNodesInSeg->getNumberOfTuples()),nodesCnt(getNumberOfNodes());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach);
+  MEDCouplingAutoRefCountObjectPtr<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]);
+          MEDCouplingAutoRefCountObjectPtr<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);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo(DataArrayDouble::Aggregate(getCoords(),addCoo));//info are copied from getCoords() by using Aggregate
+  setCoords(coo);
+  return addCoo->getNumberOfTuples();
+}
+
 MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)),
                                                                                    _own_cell(true),_cell_id(-1),_nb_cell(0)
 {