Salome HOME
Debug on GENERAL_24 and GENERAL_48
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingPointSet.cxx
index 808ce986c35c1f3e477804ad43b865e549779850..961fb248ae519aea59adff548a442cc6d5e52aba 100644 (file)
@@ -389,8 +389,8 @@ 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);
-  setCoords(newCoords);
   renumberNodesInConn(newNodeNumbers);
+  setCoords(newCoords);//let it here not before renumberNodesInConn because old number of nodes is sometimes used...
 }
 
 /*!
@@ -782,18 +782,25 @@ DataArrayDouble *MEDCouplingPointSet::MergeNodesArray(const std::vector<const ME
   std::vector<const DataArrayDouble *> coo(ms.size());
   int spaceDim=(*it)->getSpaceDimension();
   coo[0]=(*it++)->getCoords();
+  if(!coo[0]->isAllocated())
+    throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : first element in coordinates is not allocated !");
   for(int i=1;it!=ms.end();it++,i++)
     {
       const DataArrayDouble *tmp=(*it)->getCoords();
       if(tmp)
         {
-          if((*it)->getSpaceDimension()==spaceDim)
-            coo[i]=tmp;
+          if(tmp->isAllocated())
+            {
+              if((*it)->getSpaceDimension()==spaceDim)
+                coo[i]=tmp;
+              else
+                throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : Mismatch in SpaceDim !");
+            }
           else
-            throw INTERP_KERNEL::Exception("Mismatch in SpaceDim during call of MergeNodesArray !");
+            throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : Presence of a non allocated array !");
         }
       else
-        throw INTERP_KERNEL::Exception("Empty coords detected during call of MergeNodesArray !");
+        throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : Empty coords detected !");
     }
   return DataArrayDouble::Aggregate(coo);
 }
@@ -1465,3 +1472,124 @@ void MEDCouplingPointSet::checkFastEquivalWith(const MEDCouplingMesh *other, dou
   if(!status)
     throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not equal because on 3 test cells some difference have been detected !");
 }
+
+/*!
+ * Finds cells whose all or some nodes are in a given array of node ids.
+ *  \param [in] begin - the array of node ids.
+ *  \param [in] end - a pointer to the (last+1)-th element of \a begin.
+ *  \param [in] fullyIn - if \c true, then cells whose all nodes are in the
+ *         array \a begin are returned only, else cells whose any node is in the
+ *         array \a begin are returned.
+ *  \return DataArrayInt * - a new instance of DataArrayInt holding ids of found
+ *         cells. 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.
+ *  \throw If any cell id in \a begin is not valid.
+ *
+ * \sa MEDCouplingPointSet::getCellIdsFullyIncludedInNodeIds
+ *
+ *  \ref cpp_mcumesh_getCellIdsLyingOnNodes "Here is a C++ example".<br>
+ *  \ref  py_mcumesh_getCellIdsLyingOnNodes "Here is a Python example".
+ */
+DataArrayInt *MEDCouplingPointSet::getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const
+{
+  DataArrayInt *cellIdsKept=0;
+  fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept);
+  cellIdsKept->setName(getName().c_str());
+  return cellIdsKept;
+}
+
+/*!
+ * Finds cells whose all nodes are in a given array of node ids.
+ * This method is a specialization of MEDCouplingPointSet::getCellIdsLyingOnNodes (true
+ * as last input argument).
+ *  \param [in] partBg - the array of node ids.
+ *  \param [in] partEnd - a pointer to a (last+1)-th element of \a partBg.
+ *  \return DataArrayInt * - a new instance of DataArrayInt holding ids of found
+ *          cells. 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.
+ *  \throw If any cell id in \a partBg is not valid.
+ * 
+ * \sa MEDCouplingPointSet::getCellIdsLyingOnNodes
+ *
+ *  \ref cpp_mcumesh_getCellIdsFullyIncludedInNodeIds "Here is a C++ example".<br>
+ *  \ref  py_mcumesh_getCellIdsFullyIncludedInNodeIds "Here is a Python example".
+ */
+DataArrayInt *MEDCouplingPointSet::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const
+{
+  return getCellIdsLyingOnNodes(partBg,partEnd,true);
+}
+
+/*!
+ * Removes unused nodes (the node coordinates array is shorten) and returns an array
+ * mapping between new and old node ids in "Old to New" mode. -1 values in the returned
+ * array mean that the corresponding old node is no more used. 
+ *  \return DataArrayInt * - a new instance of DataArrayInt of length \a
+ *           this->getNumberOfNodes() before call of this method. 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.
+ *  \throw If the nodal connectivity includes an invalid id.
+ *
+ *  \ref cpp_mcumesh_zipCoordsTraducer "Here is a C++ example".<br>
+ *  \ref  py_mcumesh_zipCoordsTraducer "Here is a Python example".
+ */
+DataArrayInt *MEDCouplingPointSet::zipCoordsTraducer() throw(INTERP_KERNEL::Exception)
+{
+  int newNbOfNodes=-1;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> traducer=getNodeIdsInUse(newNbOfNodes);
+  renumberNodes(traducer->getConstPointer(),newNbOfNodes);
+  return traducer.retn();
+}
+
+/*!
+ * Merges nodes equal within \a precision and returns an array describing the 
+ * permutation used to remove duplicate nodes.
+ *  \param [in] precision - minimal absolute distance between two nodes at which they are
+ *              considered not coincident.
+ *  \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
+ *          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.
+ *
+ *  \ref cpp_mcumesh_mergeNodes "Here is a C++ example".<br>
+ *  \ref  py_mcumesh_mergeNodes "Here is a Python example".
+ */
+DataArrayInt *MEDCouplingPointSet::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes)
+{
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
+  if(areNodesMerged)
+    renumberNodes(ret->begin(),newNbOfNodes);
+  return ret.retn();
+}
+
+/*!
+ * Merges nodes equal within \a precision and returns an array describing the 
+ * permutation used to remove duplicate nodes. In contrast to mergeNodes(), location
+ *  of merged nodes is changed to be at their barycenter.
+ *  \param [in] precision - minimal absolute distance between two nodes at which they are
+ *              considered not coincident.
+ *  \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
+ *          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.
+ *
+ *  \ref cpp_mcumesh_mergeNodes "Here is a C++ example".<br>
+ *  \ref  py_mcumesh_mergeNodes "Here is a Python example".
+ */
+DataArrayInt *MEDCouplingPointSet::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes)
+{
+  DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
+  if(areNodesMerged)
+    renumberNodes2(ret->getConstPointer(),newNbOfNodes);
+  return ret;
+}