From 189d506dae40c9e86f61b148daee864752a96586 Mon Sep 17 00:00:00 2001 From: geay Date: Wed, 25 Jun 2014 09:58:23 +0200 Subject: [PATCH] Merged nodes detected by geometric2D are used to take advantage on 2D split mesh build phase. --- .../Geometric2D/InterpKernelGeo2DEdge.cxx | 34 +++++++++++++++++ .../Geometric2D/InterpKernelGeo2DEdge.hxx | 3 ++ .../InterpKernelGeo2DQuadraticPolygon.cxx | 7 +++- .../InterpKernelGeo2DQuadraticPolygon.hxx | 2 +- src/MEDCoupling/MEDCouplingUMesh.cxx | 38 +++++++++++++------ src/MEDCoupling/MEDCouplingUMesh.hxx | 2 +- 6 files changed, 72 insertions(+), 14 deletions(-) diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx index 479161824..95bced1da 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx @@ -163,6 +163,40 @@ unsigned MergePoints::getNumberOfAssociations() const return ret; } +void MergePoints::PushInMap(int key, int value, std::map& mergedNodes) +{ + if(key!=-1 && value!=-1) + mergedNodes[key]=value; +} + +void MergePoints::updateMergedNodes(int e1Start, int e1End, int e2Start, int e2End, std::map& mergedNodes) +{ + unsigned subTot(_ass1Start1+_ass1End1+_ass1Start2+_ass1End2); + if(subTot!=0) + { + if(_ass1Start1 && _ass1Start2) + PushInMap(e2Start,e1Start,mergedNodes); + if(_ass1Start1 && _ass1End2) + PushInMap(e2End,e1Start,mergedNodes); + if(_ass1End1 && _ass1Start2) + PushInMap(e2Start,e1End,mergedNodes); + if(_ass1End1 && _ass1End2) + PushInMap(e2End,e1End,mergedNodes); + } + subTot=_ass2Start1+_ass2End1+_ass2Start2+_ass2End2; + if(subTot!=0) + { + if(_ass2Start1 && _ass2Start2) + PushInMap(e2Start,e1Start,mergedNodes); + if(_ass2Start1 && _ass2End2) + PushInMap(e2End,e1Start,mergedNodes); + if(_ass2End1 && _ass2Start2) + PushInMap(e2Start,e1End,mergedNodes); + if(_ass2End1 && _ass2End2) + PushInMap(e2End,e1End,mergedNodes); + } +} + IntersectElement::IntersectElement(double val1, double val2, bool start1, bool end1, bool start2, bool end2, Node *node , const Edge& e1, const Edge& e2, bool keepOrder):_1S(keepOrder?start1:start2), _1E(keepOrder?end1:end2), diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx index 857aa9f42..5fd0998ac 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx @@ -82,6 +82,9 @@ namespace INTERP_KERNEL bool isEnd2(unsigned rk) const; void clear(); unsigned getNumberOfAssociations() const; + void updateMergedNodes(int e1Start, int e1End, int e2Start, int e2End, std::map& mergedNodes); + private: + static void PushInMap(int key, int value, std::map& mergedNodes); private: unsigned _ass1Start1 : 1; unsigned _ass1End1 : 1; diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx index e2cc20288..807e45ba9 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx @@ -274,7 +274,7 @@ void QuadraticPolygon::splitAbs(QuadraticPolygon& other, const std::vector& otherEdgeIds, std::vector& edgesThis, int cellIdThis, std::vector< std::vector >& edgesInOtherColinearWithThis, std::vector< std::vector >& subDivOther, - std::vector& addCoo) + std::vector& addCoo, std::map& mergedNodes) { double xBaryBB, yBaryBB; double fact=normalizeExt(&other, xBaryBB, yBaryBB); @@ -302,6 +302,10 @@ void QuadraticPolygon::splitAbs(QuadraticPolygon& other, { ElementaryEdge* curE1=it1.current(); merge.clear(); + // + std::map::const_iterator thisStart(mapThis.find(curE1->getStartNode())),thisEnd(mapThis.find(curE1->getEndNode())),otherStart(mapOther.find(curE2->getStartNode())),otherEnd(mapOther.find(curE2->getEndNode())); + int thisStart2(thisStart==mapThis.end()?-1:(*thisStart).second),thisEnd2(thisEnd==mapThis.end()?-1:(*thisEnd).second),otherStart2(otherStart==mapOther.end()?-1:(*otherStart).second+offset1),otherEnd2(otherEnd==mapOther.end()?-1:(*otherEnd).second+offset1); + // if(curE1->getPtr()->intersectWith(curE2->getPtr(),merge,*c1,*c2)) { if(!curE1->getDirection()) c1->reverse(); @@ -325,6 +329,7 @@ void QuadraticPolygon::splitAbs(QuadraticPolygon& other, UpdateNeighbours(merge,it1,it2,curE1,curE2); it1.next(); } + merge.updateMergedNodes(thisStart2,thisEnd2,otherStart2,otherEnd2,mergedNodes); } } if(otherTmp.presenceOfOn()) diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx index 99a33fefe..aefd1fefd 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx @@ -64,7 +64,7 @@ namespace INTERP_KERNEL //! Before intersecting as intersectWith a normalization is done. INTERPKERNEL_EXPORT double intersectWithAbs(QuadraticPolygon& other, double* barycenter); INTERPKERNEL_EXPORT void splitAbs(QuadraticPolygon& other, const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, const std::vector& otherEdgeIds, - std::vector& edgesThis, int cellIdThis, std::vector< std::vector >& edgesInOtherColinearWithThis, std::vector< std::vector >& subDivOther, std::vector& addCoo); + std::vector& edgesThis, int cellIdThis, std::vector< std::vector >& edgesInOtherColinearWithThis, std::vector< std::vector >& subDivOther, std::vector& addCoo, std::map& mergedNodes); INTERPKERNEL_EXPORT void buildFromCrudeDataArray(const std::map& mapp, bool isQuad, const int *nodalBg, const double *coords, const int *descBg, const int *descEnd, const std::vector >& intersectEdges); INTERPKERNEL_EXPORT void buildFromCrudeDataArray2(const std::map& mapp, bool isQuad, const int *nodalBg, const double *coords, const int *descBg, const int *descEnd, const std::vector >& intersectEdges, diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index aa4438c5b..8cab0b174 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -8755,7 +8755,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1 } //tony to put in private of MEDCouplingUMesh -MEDCouplingUMesh *BuildMesh1DCutFrom(const MEDCouplingUMesh *mesh1D, const std::vector< std::vector >& intersectEdge2, const DataArrayDouble *coords1, const std::vector& addCoo) +MEDCouplingUMesh *BuildMesh1DCutFrom(const MEDCouplingUMesh *mesh1D, const std::vector< std::vector >& intersectEdge2, const DataArrayDouble *coords1, const std::vector& addCoo, const std::map& mergedNodes) { int nCells(mesh1D->getNumberOfCells()); if(nCells!=(int)intersectEdge2.size()) @@ -8777,14 +8777,20 @@ MEDCouplingUMesh *BuildMesh1DCutFrom(const MEDCouplingUMesh *mesh1D, const std:: int nbSubEdge(subEdges.size()/2); for(int j=0;j n1(MEDCouplingUMeshBuildQPNode(subEdges[2*j],coords1->begin(),offset1,coo2Ptr,offset2,addCoo)); - MEDCouplingAutoRefCountObjectPtr n2(MEDCouplingUMeshBuildQPNode(subEdges[2*j+1],coords1->begin(),offset1,coo2Ptr,offset2,addCoo)); + MEDCouplingAutoRefCountObjectPtr n1(MEDCouplingUMeshBuildQPNode(subEdges[2*j],coords1->begin(),offset1,coo2Ptr,offset2,addCoo)),n2(MEDCouplingUMeshBuildQPNode(subEdges[2*j+1],coords1->begin(),offset1,coo2Ptr,offset2,addCoo)); MEDCouplingAutoRefCountObjectPtr e2(e->buildEdgeLyingOnMe(n1,n2)); INTERP_KERNEL::Edge *e2Ptr(e2); + std::map::const_iterator itm; if(dynamic_cast(e2Ptr)) { tmp[0]=INTERP_KERNEL::NORM_SEG3; - tmp[1]=subEdges[2*j]; tmp[2]=subEdges[2*j+1]; + itm=mergedNodes.find(subEdges[2*j]); + tmp[1]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j]; + itm=mergedNodes.find(subEdges[2*j+1]); + tmp[2]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j+1]; + tmp[3]=offset3+(int)addCooQuad.size()/2; + double tmp2[2]; + e2->getBarycenter(tmp2); addCooQuad.insert(addCooQuad.end(),tmp2,tmp2+2); cicnt+=4; cOut->insertAtTheEnd(tmp,tmp+4); ciOut->pushBackSilent(cicnt); @@ -8792,13 +8798,15 @@ MEDCouplingUMesh *BuildMesh1DCutFrom(const MEDCouplingUMesh *mesh1D, const std:: else { tmp[0]=INTERP_KERNEL::NORM_SEG2; - tmp[1]=subEdges[2*j]; tmp[2]=subEdges[2*j+1]; tmp[3]=offset3+(int)addCooQuad.size()/2; + itm=mergedNodes.find(subEdges[2*j]); + tmp[1]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j]; + itm=mergedNodes.find(subEdges[2*j+1]); + tmp[2]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j+1]; cicnt+=3; cOut->insertAtTheEnd(tmp,tmp+3); ciOut->pushBackSilent(cicnt); } } - //INTERP_KERNEL::Edge *e2(e->buildEdgeLyingOnMe()); for(std::map::const_iterator it2=m.begin();it2!=m.end();it2++) (*it2).first->decrRef(); e->decrRef(); @@ -8815,6 +8823,11 @@ MEDCouplingUMesh *BuildMesh1DCutFrom(const MEDCouplingUMesh *mesh1D, const std:: return ret.retn(); } +/*MEDCouplingUMesh *BuildMesh2DCutFrom(const MEDCouplingUMesh *mesh2D, const MEDCouplingUMesh *splitMesh1D, const DataArrayInt *elts, const DataArrayInt *eltsI) +{ + +}*/ + /*! * Partitions the first given 2D mesh using the second given 1D mesh as a tool. * Thus the final result contains all nodes from m1 plus new nodes. However it doesn't necessarily contains @@ -8849,7 +8862,8 @@ void MEDCouplingUMesh::Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D, DataArrayInt *desc1(DataArrayInt::New()),*descIndx1(DataArrayInt::New()),*revDesc1(DataArrayInt::New()),*revDescIndx1(DataArrayInt::New()); MEDCouplingAutoRefCountObjectPtr dd1(desc1),dd2(descIndx1),dd3(revDesc1),dd4(revDescIndx1); MEDCouplingAutoRefCountObjectPtr m1Desc(mesh2D->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1)); - Intersect1DMeshes(m1Desc,mesh1D,eps,intersectEdge1,colinear2,subDiv2,addCoo); + std::map mergedNodes; + Intersect1DMeshes(m1Desc,mesh1D,eps,intersectEdge1,colinear2,subDiv2,addCoo,mergedNodes); MEDCouplingAutoRefCountObjectPtr addCooDa(DataArrayDouble::New()); addCooDa->useArray(&addCoo[0],false,C_DEALLOC,(int)addCoo.size()/2,2); // Step 2: re-order newly created nodes according to the ordering found in m2 @@ -8857,7 +8871,7 @@ void MEDCouplingUMesh::Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D, BuildIntersectEdges(m1Desc,mesh1D,addCoo,subDiv2,intersectEdge2); subDiv2.clear(); // - MEDCouplingAutoRefCountObjectPtr ret1(BuildMesh1DCutFrom(mesh1D,intersectEdge2,mesh2D->getCoords(),addCoo)); + MEDCouplingAutoRefCountObjectPtr ret1(BuildMesh1DCutFrom(mesh1D,intersectEdge2,mesh2D->getCoords(),addCoo,mergedNodes)); MEDCouplingAutoRefCountObjectPtr baryRet1(ret1->getBarycenterAndOwner()); MEDCouplingAutoRefCountObjectPtr elts,eltsIndex; mesh2D->getCellsContainingPoints(baryRet1->begin(),baryRet1->getNumberOfTuples(),eps,elts,eltsIndex); @@ -9220,9 +9234,10 @@ DataArrayInt *MEDCouplingUMesh::colinearize2D(double eps) * \param [out] subDiv2 - for each cell in \a m2Desc returns nodes that split it using convention \a m1Desc first, then \a m2Desc, then addCoo * \param [out] colinear2 - for each cell in \a m2Desc returns the edges in \a m1Desc that are colinear to it. * \param [out] addCoo - nodes to be append at the end + * \param [out] mergedNodes - gives all pair of nodes of \a m2Desc that have same location than some nodes in \a m1Desc. key is id in \a m2Desc offseted and value is id in \a m1Desc. */ void MEDCouplingUMesh::Intersect1DMeshes(const MEDCouplingUMesh *m1Desc, const MEDCouplingUMesh *m2Desc, double eps, - std::vector< std::vector >& intersectEdge1, std::vector< std::vector >& colinear2, std::vector< std::vector >& subDiv2, std::vector& addCoo) + std::vector< std::vector >& intersectEdge1, std::vector< std::vector >& colinear2, std::vector< std::vector >& subDiv2, std::vector& addCoo, std::map& mergedNodes) { static const int SPACEDIM=2; INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; @@ -9262,7 +9277,7 @@ void MEDCouplingUMesh::Intersect1DMeshes(const MEDCouplingUMesh *m1Desc, const M { (*itt)->incrRef(); nodesSafe[iii]=*itt; } // end of protection // Performs egde cutting: - pol1->splitAbs(*pol2,map1,map2,offset1,offset2,candidates2,intersectEdge1[i],i,colinear2,subDiv2,addCoo); + pol1->splitAbs(*pol2,map1,map2,offset1,offset2,candidates2,intersectEdge1[i],i,colinear2,subDiv2,addCoo,mergedNodes); delete pol2; delete pol1; } @@ -9294,7 +9309,8 @@ void MEDCouplingUMesh::IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, c m1Desc=m1->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1); m2Desc=m2->buildDescendingConnectivity2(desc2,descIndx2,revDesc2,revDescIndx2); MEDCouplingAutoRefCountObjectPtr dd9(m1Desc),dd10(m2Desc); - Intersect1DMeshes(m1Desc,m2Desc,eps,intersectEdge1,colinear2,subDiv2,addCoo); + std::map notUsedMap; + Intersect1DMeshes(m1Desc,m2Desc,eps,intersectEdge1,colinear2,subDiv2,addCoo,notUsedMap); m1Desc->incrRef(); desc1->incrRef(); descIndx1->incrRef(); revDesc1->incrRef(); revDescIndx1->incrRef(); m2Desc->incrRef(); desc2->incrRef(); descIndx2->incrRef(); revDesc2->incrRef(); revDescIndx2->incrRef(); } diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index e66013411..e8e4f0c1c 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -310,7 +310,7 @@ namespace ParaMEDMEM static DataArrayInt *ComputeSpreadZoneGraduallyFromSeedAlg(std::vector& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed); static void FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt); static void AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector& ret); - static void Intersect1DMeshes(const MEDCouplingUMesh *m1Desc, const MEDCouplingUMesh *m2Desc, double eps, std::vector< std::vector >& intersectEdge1, std::vector< std::vector >& colinear2, std::vector< std::vector >& subDiv2, std::vector& addCoo); + static void Intersect1DMeshes(const MEDCouplingUMesh *m1Desc, const MEDCouplingUMesh *m2Desc, double eps, std::vector< std::vector >& intersectEdge1, std::vector< std::vector >& colinear2, std::vector< std::vector >& subDiv2, std::vector& addCoo, std::map& mergedNodes); static void IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, std::vector< std::vector >& intersectEdge1, std::vector< std::vector >& colinear2, std::vector< std::vector >& subDiv2, MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1, -- 2.39.2