]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Addition of MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords.
authorageay <ageay>
Wed, 25 Apr 2012 06:52:24 +0000 (06:52 +0000)
committerageay <ageay>
Wed, 25 Apr 2012 06:52:24 +0000 (06:52 +0000)
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx
src/MEDCoupling_Swig/MEDCoupling.i

index c3722695a41894dab4b15ac086dc8fac520cb735..4122a4af043b0c51881c463105eb8716a5b5f6c8 100644 (file)
@@ -5061,13 +5061,13 @@ MEDCouplingUMesh *MEDCouplingUMesh::FuseUMeshesOnSameCoords(const std::vector<co
  * This method takes in input meshes \b meshes containing no null reference. If any an INTERP_KERNEL::Exception will be thrown.
  * \b meshes should have a good coherency (connectivity and coordinates well defined).
  * All mesh in \b meshes must have the same space dimension. If not an INTERP_KERNEL:Exception will be thrown.
- * But mesh in \b meshes can have different mesh dimension each other.
+ * But mesh in \b meshes \b can \b have \b different \b mesh \b dimension \b each \b other.
  *
  * This method performs nothing if size of \b meshes is in [0,1].
  * This method is particulary usefull in MEDLoader context to build a \ref ParaMEDMEM::MEDFileUMesh "MEDFileUMesh" instance that expects that underlying
  * coordinates DataArrayDouble instance.
  *
- * \param [in,out] meshes
+ * \param [in,out] meshes : vector containing no null instance of MEDCouplingUMesh that in case of success of this method will be modified.
  */
 void MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(const std::vector<MEDCouplingUMesh *>& meshes) throw(INTERP_KERNEL::Exception)
 {
@@ -5100,16 +5100,71 @@ void MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(const std::vector<MEDCou
     }
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> res=DataArrayDouble::Aggregate(coords);
   std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin();
-  (*it)->setCoords(res);
-  int offset=(*it++)->getNumberOfNodes();
+  int offset=(*it)->getNumberOfNodes();
+  (*it++)->setCoords(res);
   for(;it!=meshes.end();it++)
     {
+      int oldNumberOfNodes=(*it)->getNumberOfNodes();
       (*it)->setCoords(res);
       (*it)->shiftNodeNumbersInConn(offset);
-      offset+=(*it)->getNumberOfNodes();
+      offset+=oldNumberOfNodes;
     }
 }
 
+/*!
+ * This method takes in input meshes \b meshes containing no null reference. If any an INTERP_KERNEL::Exception will be thrown.
+ * \b meshes should have a good coherency (connectivity and coordinates well defined).
+ * All mesh in \b meshes must have the same space dimension. If not an INTERP_KERNEL:Exception will be thrown.
+ * But mesh in \b meshes \b can \b have \b different \b mesh \b dimension \b each \b other.
+ * If \b meshes share the same instance of DataArrayDouble as coordinates and that this instance is null, this method do nothing and no exception will be thrown.
+ *
+ * This method performs nothing if size of \b meshes is empty.
+ * This method is particulary usefull in MEDLoader context to perform a treatment of a MEDFileUMesh instance on different levels.
+ * coordinates DataArrayDouble instance.
+ *
+ * \param [in,out] meshes :vector containing no null instance of MEDCouplingUMesh sharing the same DataArrayDouble instance of coordinates, that in case of success of this method will be modified.
+ * \param [in] eps is the distance in absolute (that should be positive !), so that 2 or more points within a distance of eps will be merged into a single point.
+ */
+void MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector<MEDCouplingUMesh *>& meshes, double eps) throw(INTERP_KERNEL::Exception)
+{
+  if(meshes.empty())
+    return ;
+  std::set<const DataArrayDouble *> s;
+  for(std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++)
+    {
+      if(*it)
+        s.insert((*it)->getCoords());
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords : In input vector of unstructured meshes of size " << meshes.size() << " the element #" << std::distance(meshes.begin(),it) << " is null !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  if(s.size()!=1)
+    {
+      std::ostringstream oss; oss << "MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords : In input vector of unstructured meshes of size " << meshes.size() << ", it appears that they do not share the same instance of DataArrayDouble for coordiantes ! tryToShareSameCoordsPermute method can help to reach that !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  const DataArrayDouble *coo=*(s.begin());
+  if(!coo)
+    return;
+  //
+  DataArrayInt *comm,*commI;
+  coo->findCommonTuples(eps,-1,comm,commI);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1(comm),tmp2(commI);
+  int oldNbOfNodes=coo->getNumberOfTuples();
+  int newNbOfNodes;
+  DataArrayInt *o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfNodes,comm,commI,newNbOfNodes);
+  if(oldNbOfNodes==newNbOfNodes)
+    return ;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->renumberAndReduce(o2n->getConstPointer(),newNbOfNodes);
+  for(std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++)
+    {
+      (*it)->renumberNodesInConn(o2n->getConstPointer());
+      (*it)->setCoords(newCoords);
+    } 
+}
+
 /*!
  * This method takes in input a cell defined by its MEDcouplingUMesh connectivity [connBg,connEnd) and returns its extruded cell by inserting the result at the end of ret.
  * @param nbOfNodesPerLev in parameter that specifies the number of nodes of one slice of global dataset
index 33cef4419bbf89d05409b8effe7f01811ab32620..d508a18ee0cadc1730ac70556cf54938a5ce959c 100644 (file)
@@ -185,6 +185,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& meshes);
     MEDCOUPLING_EXPORT static MEDCouplingUMesh *FuseUMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& meshes, int compType, std::vector<DataArrayInt *>& corr);
     MEDCOUPLING_EXPORT static void PutUMeshesOnSameAggregatedCoords(const std::vector<MEDCouplingUMesh *>& meshes) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static void MergeNodesOnUMeshesSharingSameCoords(const std::vector<MEDCouplingUMesh *>& meshes, double eps) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static bool IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords);
     MEDCOUPLING_EXPORT static bool IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords);
     MEDCOUPLING_EXPORT static void TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception);
index bb2c95a2fcd512131a6715379e0e113507bbfd48..ff5248797659a9cfd4aad0f90e3684a2d6393577 100644 (file)
@@ -715,14 +715,19 @@ void MEDCouplingBasicsTest5::testRenumberNodesInConn1()
   MEDCouplingUMesh *mesh3D_2=dynamic_cast<MEDCouplingUMesh *>(mesh3D->deepCpy());
   MEDCouplingUMesh *mesh2D_2=dynamic_cast<MEDCouplingUMesh *>(mesh2D->deepCpy());
   DataArrayInt *renumNodes=DataArrayInt::New();
+  int oldNbOf3DNodes=mesh3D->getNumberOfNodes();
   renumNodes->alloc(mesh2D->getNumberOfNodes(),1);
-  renumNodes->iota(mesh3D->getNumberOfNodes());
+  renumNodes->iota(oldNbOf3DNodes);
   DataArrayDouble *coo=DataArrayDouble::Aggregate(mesh3D->getCoords(),mesh2D->getCoords());
   mesh3D->setCoords(coo);
   mesh2D->setCoords(coo);
   coo->decrRef();
+  MEDCouplingUMesh *mesh2D_3=dynamic_cast<MEDCouplingUMesh *>(mesh2D->deepCpy());
+  mesh2D_3->shiftNodeNumbersInConn(oldNbOf3DNodes);
   mesh2D->renumberNodesInConn(renumNodes->getConstPointer());
   renumNodes->decrRef();
+  CPPUNIT_ASSERT(mesh2D_3->isEqual(mesh2D,1e-12));
+  mesh2D_3->decrRef();
   //
   DataArrayInt *da1,*da2;
   mesh3D->checkGeoEquivalWith(mesh3D_2,10,1e-12,da1,da2);
index c2520d3b3290b5de20814f28dfac55a8fc6cf983..f583c0162eaad1888a06bd4119c4e21cd52a96fb 100644 (file)
@@ -1280,6 +1280,13 @@ namespace ParaMEDMEM
         MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(meshes);
       }
 
+      static void MergeNodesOnUMeshesSharingSameCoords(PyObject *ms, double eps) throw(INTERP_KERNEL::Exception)
+      {
+        std::vector<MEDCouplingUMesh *> meshes;
+        convertPyObjToVecUMeshes(ms,meshes);
+        MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(meshes,eps);
+      }
+
       PyObject *are2DCellsNotCorrectlyOriented(PyObject *vec, bool polyOnly) const throw(INTERP_KERNEL::Exception)
       {
         std::vector<int> cells;