From: ageay Date: Wed, 25 Apr 2012 06:52:24 +0000 (+0000) Subject: Addition of MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords. X-Git-Tag: TRIPOLI_323~23 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=182d4fd49ed8077b830e8792c7703c8b472c9ffd;p=tools%2Fmedcoupling.git Addition of MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords. --- diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index c3722695a..4122a4af0 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -5061,13 +5061,13 @@ MEDCouplingUMesh *MEDCouplingUMesh::FuseUMeshesOnSameCoords(const std::vector& meshes) throw(INTERP_KERNEL::Exception) { @@ -5100,16 +5100,71 @@ void MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(const std::vector res=DataArrayDouble::Aggregate(coords); std::vector::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& meshes, double eps) throw(INTERP_KERNEL::Exception) +{ + if(meshes.empty()) + return ; + std::set s; + for(std::vector::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 tmp1(comm),tmp2(commI); + int oldNbOfNodes=coo->getNumberOfTuples(); + int newNbOfNodes; + DataArrayInt *o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfNodes,comm,commI,newNbOfNodes); + if(oldNbOfNodes==newNbOfNodes) + return ; + MEDCouplingAutoRefCountObjectPtr newCoords=coo->renumberAndReduce(o2n->getConstPointer(),newNbOfNodes); + for(std::vector::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 diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index 33cef4419..d508a18ee 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -185,6 +185,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const std::vector& meshes); MEDCOUPLING_EXPORT static MEDCouplingUMesh *FuseUMeshesOnSameCoords(const std::vector& meshes, int compType, std::vector& corr); MEDCOUPLING_EXPORT static void PutUMeshesOnSameAggregatedCoords(const std::vector& meshes) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static void MergeNodesOnUMeshesSharingSameCoords(const std::vector& 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); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx index bb2c95a2f..ff5248797 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx @@ -715,14 +715,19 @@ void MEDCouplingBasicsTest5::testRenumberNodesInConn1() MEDCouplingUMesh *mesh3D_2=dynamic_cast(mesh3D->deepCpy()); MEDCouplingUMesh *mesh2D_2=dynamic_cast(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(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); diff --git a/src/MEDCoupling_Swig/MEDCoupling.i b/src/MEDCoupling_Swig/MEDCoupling.i index c2520d3b3..f583c0162 100644 --- a/src/MEDCoupling_Swig/MEDCoupling.i +++ b/src/MEDCoupling_Swig/MEDCoupling.i @@ -1280,6 +1280,13 @@ namespace ParaMEDMEM MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(meshes); } + static void MergeNodesOnUMeshesSharingSameCoords(PyObject *ms, double eps) throw(INTERP_KERNEL::Exception) + { + std::vector meshes; + convertPyObjToVecUMeshes(ms,meshes); + MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(meshes,eps); + } + PyObject *are2DCellsNotCorrectlyOriented(PyObject *vec, bool polyOnly) const throw(INTERP_KERNEL::Exception) { std::vector cells;