Salome HOME
getCellsContainingPoints is sensitive to 2D quadratic static cells.
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingPointSet.cxx
index d20b60567aaf15a039279a10fe65040a89b76a76..1f8b34bccd063146c2d1da9d472ca03043ac34d9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D
+// 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
@@ -19,7 +19,7 @@
 // Author : Anthony Geay (CEA/DEN)
 
 #include "MEDCouplingPointSet.hxx"
-#include "MEDCouplingAutoRefCountObjectPtr.hxx"
+#include "MCAuto.hxx"
 #include "MEDCoupling1GTUMesh.hxx"
 #include "MEDCouplingUMesh.hxx"
 #include "MEDCouplingMemArray.hxx"
 #include <cmath>
 #include <limits>
 #include <numeric>
+#include <sstream>
 
-using namespace ParaMEDMEM;
+using namespace MEDCoupling;
 
 MEDCouplingPointSet::MEDCouplingPointSet():_coords(0)
 {
 }
 
-MEDCouplingPointSet::MEDCouplingPointSet(const MEDCouplingPointSet& other, bool deepCopy):MEDCouplingMesh(other),_coords(0)
+MEDCouplingPointSet::MEDCouplingPointSet(const MEDCouplingPointSet& other, bool deepCpy):MEDCouplingMesh(other),_coords(0)
 {
   if(other._coords)
-    _coords=other._coords->performCpy(deepCopy);
+    _coords=other._coords->performCopyOrIncrRef(deepCpy);
 }
 
 MEDCouplingPointSet::~MEDCouplingPointSet()
@@ -80,11 +81,10 @@ std::size_t MEDCouplingPointSet::getHeapMemorySizeWithoutChildren() const
   return MEDCouplingMesh::getHeapMemorySizeWithoutChildren();
 }
 
-std::vector<const BigMemoryObject *> MEDCouplingPointSet::getDirectChildren() const
+std::vector<const BigMemoryObject *> MEDCouplingPointSet::getDirectChildrenWithNull() const
 {
   std::vector<const BigMemoryObject *> ret;
-  if(_coords)
-    ret.push_back(_coords);
+  ret.push_back(_coords);
   return ret;
 }
 
@@ -124,10 +124,10 @@ DataArrayDouble *MEDCouplingPointSet::getCoordinatesAndOwner() const
  */
 void MEDCouplingPointSet::copyTinyStringsFrom(const MEDCouplingMesh *other)
 {
+  MEDCouplingMesh::copyTinyStringsFrom(other);
   const MEDCouplingPointSet *otherC=dynamic_cast<const MEDCouplingPointSet *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::copyTinyStringsFrom : meshes have not same type !");
-  MEDCouplingMesh::copyTinyStringsFrom(other);
   if(_coords && otherC->_coords)
     _coords->copyStringInfoFrom(*otherC->_coords);
 }
@@ -257,7 +257,7 @@ void MEDCouplingPointSet::getCoordinatesOfNode(int nodeId, std::vector<double>&
  *  \param [out] areNodesMerged - is set to \a true if any coincident nodes found.
  *  \param [out] newNbOfNodes - returns number of unique nodes.
  *  \return DataArrayInt * - the permutation array in "Old to New" mode. For more 
- *          info on "Old to New" mode see \ref MEDCouplingArrayRenumbering. The caller
+ *          info on "Old to New" mode see \ref numbering. The caller
  *          is to delete this array using decrRef() as it is no more needed.
  *  \throw If the coordinates array is not set.
  */
@@ -266,7 +266,7 @@ DataArrayInt *MEDCouplingPointSet::buildPermArrayForMergeNode(double precision,
   DataArrayInt *comm,*commI;
   findCommonNodes(precision,limitNodeId,comm,commI);
   int oldNbOfNodes=getNumberOfNodes();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes);
+  MCAuto<DataArrayInt> ret=buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes);
   areNodesMerged=(oldNbOfNodes!=newNbOfNodes);
   comm->decrRef();
   commI->decrRef();
@@ -275,8 +275,7 @@ DataArrayInt *MEDCouplingPointSet::buildPermArrayForMergeNode(double precision,
 
 /*!
  * Finds nodes coincident within \a prec tolerance.
- * Ids of coincident nodes are stored in output arrays.
- * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
+ * Ids of coincident nodes are stored in output arrays in the \ref numbering-indirect format.
  *  \param [in] prec - minimal absolute distance (using infinite norm) between two nodes at which they are
  *              considered not coincident.
  *  \param [in] limitNodeId - limit node id. If all nodes within a group of coincident
@@ -287,7 +286,7 @@ DataArrayInt *MEDCouplingPointSet::buildPermArrayForMergeNode(double precision,
  *               \a comm->getNumberOfTuples() == \a commIndex->back(). The caller
  *               is to delete this array using decrRef() as it is no more needed.
  *  \param [out] commIndex - the array dividing all ids stored in \a comm into
- *               groups of (ids of) coincident nodes. Its every value is a tuple
+ *               groups of (ids of) coincident nodes (\ref numbering-indirect). Its every value is a tuple
  *               index where a next group of nodes begins. For example the second
  *               group of nodes in \a comm is described by following range of indices:
  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
@@ -328,7 +327,7 @@ DataArrayInt *MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, double
 {
   DataArrayInt *c=0,*cI=0;
   getNodeIdsNearPoints(pos,1,eps,c,cI);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cITmp(cI);
+  MCAuto<DataArrayInt> cITmp(cI);
   return c;
 }
 
@@ -341,11 +340,11 @@ DataArrayInt *MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, double
  *         parameter. 
  *  \param [in] eps - the lowest distance between (using infinite norm) a point and a node at which the node is
  *         not returned by this method.
- *  \param [out] c - array returning ids of nodes located closer than \a eps to the
+ *  \param [out] c - array (\ref numbering-indirect) returning ids of nodes located closer than \a eps to the
  *         given points. The caller
  *         is to delete this array using decrRef() as it is no more needed.
  *  \param [out] cI - for each i-th given point, the array specifies tuples of \a c
- *         holding ids of nodes close to the i-th point. <br>The i-th value of \a cI is an 
+ *         holding ids of nodes close to the i-th point (\ref numbering-indirect). <br>The i-th value of \a cI is an
  *         index of tuple of \a c holding id of a first (if any) node close to the
  *         i-th given point. Difference between the i-th and (i+1)-th value of \a cI
  *         (i.e. \a cI[ i+1 ] - \a cI[ i ]) defines number of nodes close to the i-th
@@ -364,22 +363,22 @@ void MEDCouplingPointSet::getNodeIdsNearPoints(const double *pos, int nbOfPoints
   if(!_coords)
     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getNodeIdsNearPoint : no coordiantes set !");
   int spaceDim=getSpaceDimension();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> points=DataArrayDouble::New();
+  MCAuto<DataArrayDouble> points=DataArrayDouble::New();
   points->useArray(pos,false,CPP_DEALLOC,nbOfPoints,spaceDim);
   _coords->computeTupleIdsNearTuples(points,eps,c,cI);
 }
 
 /*!
- * @param comm in param in the same format than one returned by findCommonNodes method.
- * @param commI in param in the same format than one returned by findCommonNodes method.
- * @return the old to new correspondance array.
+ * @param comm in param in the same format than one returned by findCommonNodes method (\ref numbering-indirect).
+ * @param commI in param in the same format than one returned by findCommonNodes method (\ref numbering-indirect).
+ * @return the old to new correspondence array.
  */
 DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex,
                                                                           int& newNbOfNodes) const
 {
   if(!_coords)
     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat : no coords specified !");
-  return DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfNodes(),comm->begin(),commIndex->begin(),commIndex->end(),newNbOfNodes);
+  return DataArrayInt::ConvertIndexArrayToO2N(getNumberOfNodes(),comm->begin(),commIndex->begin(),commIndex->end(),newNbOfNodes);
 }
 
 /*!
@@ -389,7 +388,7 @@ DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const
  * array is modified accordingly.
  *  \param [in] newNodeNumbers - a permutation array, of length \a
  *         this->getNumberOfNodes(), in "Old to New" mode. 
- *         See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
+ *         See \ref numbering for more info on renumbering modes.
  *  \param [in] newNbOfNodes - number of nodes remaining after renumbering.
  *  \throw If the coordinates array is not set.
  *  \throw If the nodal connectivity of cells is not defined.
@@ -403,7 +402,7 @@ void MEDCouplingPointSet::renumberNodes(const int *newNodeNumbers, int newNbOfNo
 {
   if(!_coords)
     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::renumberNodes : no coords specified !");
-  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=_coords->renumberAndReduce(newNodeNumbers,newNbOfNodes);
+  MCAuto<DataArrayDouble> newCoords=_coords->renumberAndReduce(newNodeNumbers,newNbOfNodes);
   renumberNodesInConn(newNodeNumbers);
   setCoords(newCoords);//let it here not before renumberNodesInConn because old number of nodes is sometimes used...
 }
@@ -416,7 +415,7 @@ void MEDCouplingPointSet::renumberNodes(const int *newNodeNumbers, int newNbOfNo
  * of merged nodes (whose new ids coincide) is changed to be at their barycenter.
  *  \param [in] newNodeNumbers - a permutation array, of length \a
  *         this->getNumberOfNodes(), in "Old to New" mode. 
- *         See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
+ *         See \ref numbering for more info on renumbering modes.
  *  \param [in] newNbOfNodes - number of nodes remaining after renumbering, which is
  *         actually one more than the maximal id in \a newNodeNumbers.
  *  \throw If the coordinates array is not set.
@@ -427,7 +426,7 @@ void MEDCouplingPointSet::renumberNodes(const int *newNodeNumbers, int newNbOfNo
  *  \ref  py_mcumesh_renumberNodes "Here is a Python example".
  *  \endif
  */
-void MEDCouplingPointSet::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes)
+void MEDCouplingPointSet::renumberNodesCenter(const int *newNodeNumbers, int newNbOfNodes)
 {
   DataArrayDouble *newCoords=DataArrayDouble::New();
   std::vector<int> div(newNbOfNodes);
@@ -485,10 +484,12 @@ void MEDCouplingPointSet::zipCoords()
   traducer->decrRef();
 }
 
+/*! \cond HIDDEN_ITEMS */
 struct MEDCouplingCompAbs
 {
   bool operator()(double x, double y) { return std::abs(x)<std::abs(y);}
 };
+/*! \endcond */
 
 /*!
  * Returns the carateristic dimension of \a this point set, that is a maximal
@@ -674,8 +675,8 @@ void MEDCouplingPointSet::duplicateNodesInCoords(const int *nodeIdsToDuplicateBg
 {
   if(!_coords)
     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::duplicateNodesInCoords : no coords set !");
-  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=_coords->selectByTupleIdSafe(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords2=DataArrayDouble::Aggregate(_coords,newCoords);
+  MCAuto<DataArrayDouble> newCoords=_coords->selectByTupleIdSafe(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd);
+  MCAuto<DataArrayDouble> newCoords2=DataArrayDouble::Aggregate(_coords,newCoords);
   setCoords(newCoords2);
 }
 
@@ -947,10 +948,10 @@ void MEDCouplingPointSet::unserialization(const std::vector<double>& tinyInfoD,
     }
 }
 
-void MEDCouplingPointSet::checkCoherency() const
+void MEDCouplingPointSet::checkConsistencyLight() const
 {
   if(!_coords)
-    throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkCoherency : no coordinates set !");
+    throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkConsistencyLight : no coordinates set !");
 }
 
 /*!
@@ -994,8 +995,8 @@ bool MEDCouplingPointSet::intersectsBoundingBox(const double* bb1, const double*
  */
 bool MEDCouplingPointSet::intersectsBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bb1, const double* bb2, int dim, double eps)
 {
-  double* bbtemp = new double[2*dim];
-  double deltamax=0.0;
+  double* bbtemp(new double[2*dim]);
+  double deltamax(0.0);
 
   for (int i=0; i< dim; i++)
     {
@@ -1011,7 +1012,7 @@ bool MEDCouplingPointSet::intersectsBoundingBox(const INTERP_KERNEL::DirectedBou
       bbtemp[i*2+1]=bb2[i*2+1]+deltamax*eps;
     }
   
-  bool intersects = !bb1.isDisjointWith( bbtemp );
+  bool intersects(!bb1.isDisjointWith(bbtemp));
   delete [] bbtemp;
   return intersects;
 }
@@ -1021,49 +1022,9 @@ bool MEDCouplingPointSet::intersectsBoundingBox(const INTERP_KERNEL::DirectedBou
  */
 void MEDCouplingPointSet::rotate3D(const double *center, const double *vect, double angle)
 {
-  double *coords=_coords->getPointer();
-  int nbNodes=getNumberOfNodes();
-  Rotate3DAlg(center,vect,angle,nbNodes,coords);
-}
-
-/*!
- * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in 'coords'
- * around an axe ('center','vect') and with angle 'angle'.
- */
-void MEDCouplingPointSet::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, double *coords)
-{
-  if(!center || !vect)
-    throw INTERP_KERNEL::Exception("MEDCouplingPointSet::Rotate3DAlg : null vector in input !");
-  double sina=sin(angle);
-  double cosa=cos(angle);
-  double vectorNorm[3];
-  double matrix[9];
-  double matrixTmp[9];
-  double norm=sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]);
-  if(norm<std::numeric_limits<double>::min())
-    throw INTERP_KERNEL::Exception("MEDCouplingPointSet::Rotate3DAlg : magnitude of input vector is too close of 0. !");
-  std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
-  //rotation matrix computation
-  matrix[0]=cosa; matrix[1]=0.; matrix[2]=0.; matrix[3]=0.; matrix[4]=cosa; matrix[5]=0.; matrix[6]=0.; matrix[7]=0.; matrix[8]=cosa;
-  matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
-  matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
-  matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
-  std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
-  std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
-  matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
-  matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
-  matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
-  std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
-  std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
-  //rotation matrix computed.
-  double tmp[3];
-  for(int i=0; i<nbNodes; i++)
-    {
-      std::transform(coords+i*3,coords+(i+1)*3,center,tmp,std::minus<double>());
-      coords[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
-      coords[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
-      coords[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
-    }
+  double *coords(_coords->getPointer());
+  int nbNodes(getNumberOfNodes());
+  DataArrayDouble::Rotate3DAlg(center,vect,angle,nbNodes,coords,coords);
 }
 
 /*!
@@ -1081,7 +1042,7 @@ DataArrayInt *MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells(const MED
 {
   if(!srcMesh || !trgMesh)
     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells : the input meshes must be not NULL !");
-  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> sbbox(srcMesh->getBoundingBoxForBBTree()),tbbox(trgMesh->getBoundingBoxForBBTree());
+  MCAuto<DataArrayDouble> sbbox(srcMesh->getBoundingBoxForBBTree(eps)),tbbox(trgMesh->getBoundingBoxForBBTree(eps));
   return tbbox->computeNbOfInteractionsWith(sbbox,eps);
 }
 
@@ -1115,7 +1076,7 @@ MEDCouplingMesh *MEDCouplingPointSet::buildPart(const int *start, const int *end
  */
 MEDCouplingMesh *MEDCouplingPointSet::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> ret=buildPartOfMySelf(start,end,true);
+  MCAuto<MEDCouplingPointSet> ret=buildPartOfMySelf(start,end,true);
   arr=ret->zipCoordsTraducer();
   return ret.retn();
 }
@@ -1129,7 +1090,7 @@ MEDCouplingMesh *MEDCouplingPointSet::buildPartAndReduceNodes(const int *start,
  *
  * \return a new ref to be managed by the caller. Warning this ref can be equal to \a this if input slice is exactly equal to the whole cells in the same order.
  *
- * \sa MEDCouplingUMesh::buildPartOfMySelf2
+ * \sa MEDCouplingUMesh::buildPartOfMySelfSlice
  */
 MEDCouplingMesh *MEDCouplingPointSet::buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const
 {
@@ -1141,7 +1102,7 @@ MEDCouplingMesh *MEDCouplingPointSet::buildPartRange(int beginCellIds, int endCe
     }
   else
     {
-      return buildPartOfMySelf2(beginCellIds,endCellIds,stepCellIds,true);
+      return buildPartOfMySelfSlice(beginCellIds,endCellIds,stepCellIds,true);
     }
 }
 
@@ -1151,13 +1112,13 @@ MEDCouplingMesh *MEDCouplingPointSet::buildPartRange(int beginCellIds, int endCe
  * \param [out] beginOut valid only if \a arr not NULL !
  * \param [out] endOut valid only if \a arr not NULL !
  * \param [out] stepOut valid only if \a arr not NULL !
- * \param [out] arr correspondance old to new in node ids.
+ * \param [out] arr correspondence old to new in node ids.
  * 
- * \sa MEDCouplingUMesh::buildPartOfMySelf2
+ * \sa MEDCouplingUMesh::buildPartOfMySelfSlice
  */
 MEDCouplingMesh *MEDCouplingPointSet::buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> ret=buildPartOfMySelf2(beginCellIds,endCellIds,stepCellIds,true);
+  MCAuto<MEDCouplingPointSet> ret(buildPartOfMySelfSlice(beginCellIds,endCellIds,stepCellIds,true));
   arr=ret->zipCoordsTraducer();
   return ret.retn();
 }
@@ -1167,28 +1128,9 @@ MEDCouplingMesh *MEDCouplingPointSet::buildPartRangeAndReduceNodes(int beginCell
  */
 void MEDCouplingPointSet::rotate2D(const double *center, double angle)
 {
-  double *coords=_coords->getPointer();
-  int nbNodes=getNumberOfNodes();
-  Rotate2DAlg(center,angle,nbNodes,coords);
-}
-
-/*!
- * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in 'coords'
- * around the center point 'center' and with angle 'angle'.
- */
-void MEDCouplingPointSet::Rotate2DAlg(const double *center, double angle, int nbNodes, double *coords)
-{
-  double cosa=cos(angle);
-  double sina=sin(angle);
-  double matrix[4];
-  matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
-  double tmp[2];
-  for(int i=0; i<nbNodes; i++)
-    {
-      std::transform(coords+i*2,coords+(i+1)*2,center,tmp,std::minus<double>());
-      coords[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
-      coords[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
-    }
+  double *coords(_coords->getPointer());
+  int nbNodes(getNumberOfNodes());
+  DataArrayDouble::Rotate2DAlg(center,angle,nbNodes,coords,coords);
 }
 
 /// @cond INTERNAL
@@ -1212,8 +1154,8 @@ public:
  */
 void MEDCouplingPointSet::project2DCellOnXY(const int *startConn, const int *endConn, std::vector<double>& res) const
 {
-  const double *coords=_coords->getConstPointer();
-  int spaceDim=getSpaceDimension();
+  const double *coords(_coords->getConstPointer());
+  int spaceDim(getSpaceDimension());
   for(const int *it=startConn;it!=endConn;it++)
     res.insert(res.end(),coords+spaceDim*(*it),coords+spaceDim*(*it+1));
   if(spaceDim==2)
@@ -1239,21 +1181,21 @@ void MEDCouplingPointSet::project2DCellOnXY(const int *startConn, const int *end
  */
 bool MEDCouplingPointSet::isButterfly2DCell(const std::vector<double>& res, bool isQuad, double eps)
 {
-  std::size_t nbOfNodes=res.size()/2;
+  INTERP_KERNEL::QuadraticPlanarPrecision prec(eps);
+
+  std::size_t nbOfNodes(res.size()/2);
   std::vector<INTERP_KERNEL::Node *> nodes(nbOfNodes);
   for(std::size_t i=0;i<nbOfNodes;i++)
     {
       INTERP_KERNEL::Node *tmp=new INTERP_KERNEL::Node(res[2*i],res[2*i+1]);
       nodes[i]=tmp;
     }
-  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
-  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
   INTERP_KERNEL::QuadraticPolygon *pol=0;
   if(isQuad)
     pol=INTERP_KERNEL::QuadraticPolygon::BuildArcCirclePolygon(nodes);
   else
     pol=INTERP_KERNEL::QuadraticPolygon::BuildLinearPolygon(nodes);
-  bool ret=pol->isButterflyAbs();
+  bool ret(pol->isButterflyAbs());
   delete pol;
   return ret;
 }
@@ -1269,7 +1211,7 @@ bool MEDCouplingPointSet::areCellsFrom2MeshEqual(const MEDCouplingPointSet *othe
   std::vector<int> c1,c2;
   getNodeIdsOfCell(cellId,c1);
   other->getNodeIdsOfCell(cellId,c2);
-  std::size_t sz=c1.size();
+  std::size_t sz(c1.size());
   if(sz!=c2.size())
     return false;
   for(std::size_t i=0;i<sz;i++)
@@ -1308,13 +1250,13 @@ void MEDCouplingPointSet::tryToShareSameCoordsPermute(const MEDCouplingPointSet&
   if(!_coords)
     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute : No coords specified in this whereas there is any in other !");
   int otherNbOfNodes=other.getNumberOfNodes();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=MergeNodesArray(&other,this);
+  MCAuto<DataArrayDouble> newCoords=MergeNodesArray(&other,this);
   _coords->incrRef();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> oldCoords=_coords;
+  MCAuto<DataArrayDouble> oldCoords=_coords;
   setCoords(newCoords);
   bool areNodesMerged;
   int newNbOfNodes;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=buildPermArrayForMergeNode(epsilon,otherNbOfNodes,areNodesMerged,newNbOfNodes);
+  MCAuto<DataArrayInt> da=buildPermArrayForMergeNode(epsilon,otherNbOfNodes,areNodesMerged,newNbOfNodes);
   if(!areNodesMerged)
     {
       setCoords(oldCoords);
@@ -1334,15 +1276,15 @@ void MEDCouplingPointSet::tryToShareSameCoordsPermute(const MEDCouplingPointSet&
 
 MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> ret=buildPartOfMySelfKeepCoords(begin,end);
+  MCAuto<MEDCouplingPointSet> ret=buildPartOfMySelfKeepCoords(begin,end);
   if(!keepCoords)
     ret->zipCoords();
   return ret.retn();
 }
 
-MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const
+MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelfSlice(int start, int end, int step, bool keepCoords) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> ret=buildPartOfMySelfKeepCoords2(start,end,step);
+  MCAuto<MEDCouplingPointSet> ret=buildPartOfMySelfKeepCoordsSlice(start,end,step);
   if(!keepCoords)
     ret->zipCoords();
   return ret.retn();
@@ -1375,7 +1317,7 @@ MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelfNode(const int *begin
 {
   DataArrayInt *cellIdsKept=0;
   fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept2(cellIdsKept);
+  MCAuto<DataArrayInt> cellIdsKept2(cellIdsKept);
   return buildPartOfMySelf(cellIdsKept->begin(),cellIdsKept->end(),true);
 }
 
@@ -1414,16 +1356,30 @@ DataArrayInt *MEDCouplingPointSet::zipConnectivityTraducer(int compType, int sta
 {
   DataArrayInt *commonCells=0,*commonCellsI=0;
   findCommonCells(compType,startCellId,commonCells,commonCellsI);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> commonCellsTmp(commonCells),commonCellsITmp(commonCellsI);
+  MCAuto<DataArrayInt> commonCellsTmp(commonCells),commonCellsITmp(commonCellsI);
   int newNbOfCells=-1;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfCells(),commonCells->begin(),commonCellsI->begin(),
+  MCAuto<DataArrayInt> ret=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfCells(),commonCells->begin(),commonCellsI->begin(),
                                                                                                           commonCellsI->end(),newNbOfCells);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2O(newNbOfCells);
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> self=buildPartOfMySelf(ret2->begin(),ret2->end(),true);
+  MCAuto<DataArrayInt> ret2=ret->invertArrayO2N2N2O(newNbOfCells);
+  MCAuto<MEDCouplingPointSet> self=buildPartOfMySelf(ret2->begin(),ret2->end(),true);
   shallowCopyConnectivityFrom(self);
   return ret.retn();
 }
 
+/*!
+ * This const method states if the nodal connectivity of this fetches all nodes in \a this.
+ * In other words, this method looks is there are no orphan nodes in \a this.
+ * \sa zipCoordsTraducer, getNodeIdsInUse, computeFetchedNodeIds.
+ */
+bool MEDCouplingPointSet::areAllNodesFetched() const
+{
+  checkFullyDefined();
+  int nbNodes(getNumberOfNodes());
+  std::vector<bool> fetchedNodes(nbNodes,false);
+  computeNodeIdsAlg(fetchedNodes);
+  return std::find(fetchedNodes.begin(),fetchedNodes.end(),false)==fetchedNodes.end();
+}
+
 /*!
  * Checks if \a this and \a other meshes are geometrically equivalent, else an
  * exception is thrown. The meshes are
@@ -1431,6 +1387,14 @@ DataArrayInt *MEDCouplingPointSet::zipConnectivityTraducer(int compType, int sta
  * mesh (with a specified precision) and (2) \a this mesh contains the same cells as
  * the \a other mesh (with use of a specified cell comparison technique). The mapping 
  * from \a other to \a this for nodes and cells is returned via out parameters.
+ *
+ * If \a cellCor is null (or Py_None) it means that for all #i cell in \a other is equal to cell # i in \a this.
+ *
+ * If \a nodeCor is null (or Py_None) it means that for all #i node in \a other is equal to node # i in \a this.
+ *
+ * So null (or Py_None) returned in \a cellCor and/or \a nodeCor means identity array. This is for optimization reason to avoid building
+ * useless arrays for some \a levOfCheck (for example 0).
+ *
  *  \param [in] other - the mesh to compare with.
  *  \param [in] cellCompPol - id [0-2] of cell comparison method. See meaning of
  *         each method in description of MEDCouplingPointSet::zipConnectivityTraducer().
@@ -1447,40 +1411,47 @@ DataArrayInt *MEDCouplingPointSet::zipConnectivityTraducer(int compType, int sta
  *  \endif
  */
 void MEDCouplingPointSet::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
-                                               DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
+                                               DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
 {
   if(!other)
     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalWith : input is null !");
   const MEDCouplingPointSet *otherC=dynamic_cast<const MEDCouplingPointSet *>(other);
   if(!otherC)
     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalWith : other is not a PointSet mesh !");
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> m=dynamic_cast<MEDCouplingPointSet *>(mergeMyselfWith(otherC));
+  MCAuto<MEDCouplingPointSet> m=dynamic_cast<MEDCouplingPointSet *>(mergeMyselfWith(otherC));
   bool areNodesMerged;
   int newNbOfNodes;
   int oldNbOfNodes=getNumberOfNodes();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=m->buildPermArrayForMergeNode(prec,oldNbOfNodes,areNodesMerged,newNbOfNodes);
+  MCAuto<DataArrayInt> da=m->buildPermArrayForMergeNode(prec,oldNbOfNodes,areNodesMerged,newNbOfNodes);
   //mergeNodes
-  if(!areNodesMerged)
+  if(!areNodesMerged && oldNbOfNodes != 0)
     throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Nodes are incompatible ! ");
   const int *pt=std::find_if(da->getConstPointer()+oldNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),oldNbOfNodes-1));
   if(pt!=da->getConstPointer()+da->getNbOfElems())
     throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some nodes in other are not in this !");
   m->renumberNodes(da->getConstPointer(),newNbOfNodes);
   //
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeCor2=da->substr(oldNbOfNodes);
+  MCAuto<DataArrayInt> nodeCor2=da->subArray(oldNbOfNodes);
   da=m->mergeNodes(prec,areNodesMerged,newNbOfNodes);
   //
   da=m->zipConnectivityTraducer(cellCompPol);
   int nbCells=getNumberOfCells();
-  int maxId=-1;
-  if(nbCells!=0)
-    maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+nbCells);
-  pt=std::find_if(da->getConstPointer()+nbCells,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),maxId));
-  if(pt!=da->getConstPointer()+da->getNbOfElems())
+  if (nbCells != other->getNumberOfCells())
     throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !");
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellCor2=da->selectByTupleId2(nbCells,da->getNbOfElems(),1);
-  nodeCor=nodeCor2->isIdentity()?0:nodeCor2.retn();
-  cellCor=cellCor2->isIdentity()?0:cellCor2.retn();
+  int dan(da->getNumberOfTuples());
+  if (dan)
+    {
+      MCAuto<DataArrayInt> da1(DataArrayInt::New()),da2(DataArrayInt::New());
+      da1->alloc(dan/2,1); da2->alloc(dan/2,1);
+      std::copy(da->getConstPointer(), da->getConstPointer()+dan/2, da1->getPointer());
+      std::copy(da->getConstPointer()+dan/2, da->getConstPointer()+dan, da2->getPointer());
+      da1->sort(); da2->sort();
+      if (!da1->isEqualWithoutConsideringStr(*da2))
+        throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !");
+    }
+  MCAuto<DataArrayInt> cellCor2=da->selectByTupleIdSafeSlice(nbCells,da->getNbOfElems(),1);
+  nodeCor=nodeCor2->isIota(nodeCor2->getNumberOfTuples())?0:nodeCor2.retn();
+  cellCor=cellCor2->isIota(cellCor2->getNumberOfTuples())?0:cellCor2.retn();
 }
 
 /*!
@@ -1489,6 +1460,9 @@ void MEDCouplingPointSet::checkDeepEquivalWith(const MEDCouplingMesh *other, int
  * node coordinates array and (2) they contain the same cells (with use of a specified
  * cell comparison technique). The mapping from cells of the \a other to ones of \a this 
  * is returned via an out parameter.
+ *
+ * If \a cellCor is null (or Py_None) it means that for all #i cell in \a other is equal to cell # i in \a this.
+ *
  *  \param [in] other - the mesh to compare with.
  *  \param [in] cellCompPol - id [0-2] of cell comparison method. See the meaning of
  *         each method in description of MEDCouplingPointSet::zipConnectivityTraducer().
@@ -1503,7 +1477,7 @@ void MEDCouplingPointSet::checkDeepEquivalWith(const MEDCouplingMesh *other, int
  * \endif
  */
 void MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
-                                                       DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
+                                                       DataArrayInt *&cellCor) const
 {
   if(!other)
     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith : input is null !");
@@ -1512,16 +1486,16 @@ void MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh
     throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith : other is not a PointSet mesh !");
   if(_coords!=otherC->_coords)
     throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : meshes do not share the same coordinates ! Use tryToShareSameCoordinates or call checkDeepEquivalWith !");
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> m=mergeMyselfWithOnSameCoords(otherC);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=m->zipConnectivityTraducer(cellCompPol);
+  MCAuto<MEDCouplingPointSet> m=mergeMyselfWithOnSameCoords(otherC);
+  MCAuto<DataArrayInt> da=m->zipConnectivityTraducer(cellCompPol);
   int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells());
   const int *pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),maxId));
   if(pt!=da->getConstPointer()+da->getNbOfElems())
     {
       throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : some cells in other are not in this !");
     }
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellCor2=da->selectByTupleId2(getNumberOfCells(),da->getNbOfElems(),1);
-  cellCor=cellCor2->isIdentity()?0:cellCor2.retn();
+  MCAuto<DataArrayInt> cellCor2=da->selectByTupleIdSafeSlice(getNumberOfCells(),da->getNbOfElems(),1);
+  cellCor=cellCor2->isIota(cellCor2->getNumberOfTuples())?0:cellCor2.retn();
 }
 
 void MEDCouplingPointSet::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
@@ -1615,7 +1589,7 @@ DataArrayInt *MEDCouplingPointSet::getCellIdsFullyIncludedInNodeIds(const int *p
 DataArrayInt *MEDCouplingPointSet::zipCoordsTraducer()
 {
   int newNbOfNodes=-1;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> traducer=getNodeIdsInUse(newNbOfNodes);
+  MCAuto<DataArrayInt> traducer=getNodeIdsInUse(newNbOfNodes);
   renumberNodes(traducer->getConstPointer(),newNbOfNodes);
   return traducer.retn();
 }
@@ -1628,7 +1602,7 @@ DataArrayInt *MEDCouplingPointSet::zipCoordsTraducer()
  *  \param [out] areNodesMerged - is set to \c true if any coincident nodes removed.
  *  \param [out] newNbOfNodes - number of nodes remaining after the removal.
  *  \return DataArrayInt * - the permutation array in "Old to New" mode. For more 
- *          info on "Old to New" mode see \ref MEDCouplingArrayRenumbering. The caller
+ *          info on "Old to New" mode see \ref numbering. The caller
  *          is to delete this array using decrRef() as it is no more needed.
  *  \throw If the coordinates array is not set.
  *  \throw If the nodal connectivity of cells is not defined.
@@ -1640,7 +1614,7 @@ DataArrayInt *MEDCouplingPointSet::zipCoordsTraducer()
  */
 DataArrayInt *MEDCouplingPointSet::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes)
 {
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
+  MCAuto<DataArrayInt> ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
   if(areNodesMerged)
     renumberNodes(ret->begin(),newNbOfNodes);
   return ret.retn();
@@ -1655,7 +1629,7 @@ DataArrayInt *MEDCouplingPointSet::mergeNodes(double precision, bool& areNodesMe
  *  \param [out] areNodesMerged - is set to \c true if any coincident nodes removed.
  *  \param [out] newNbOfNodes - number of nodes remaining after the removal.
  *  \return DataArrayInt * - the permutation array in "Old to New" mode. For more 
- *          info on "Old to New" mode see \ref MEDCouplingArrayRenumbering. The caller
+ *          info on "Old to New" mode see \ref numbering. The caller
  *          is to delete this array using decrRef() as it is no more needed.
  *  \throw If the coordinates array is not set.
  *  \throw If the nodal connectivity of cells is not defined.
@@ -1665,10 +1639,10 @@ DataArrayInt *MEDCouplingPointSet::mergeNodes(double precision, bool& areNodesMe
  *  \ref  py_mcumesh_mergeNodes "Here is a Python example".
  *  \endif
  */
-DataArrayInt *MEDCouplingPointSet::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes)
+DataArrayInt *MEDCouplingPointSet::mergeNodesCenter(double precision, bool& areNodesMerged, int& newNbOfNodes)
 {
   DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
   if(areNodesMerged)
-    renumberNodes2(ret->getConstPointer(),newNbOfNodes);
+    renumberNodesCenter(ret->getConstPointer(),newNbOfNodes);
   return ret;
 }