X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESHUtils%2FSMESH_Offset.cxx;h=34e3c9d26bdd7991452a30c7ff4cc85884a86a64;hb=8a0ae207320e1fcc7aa80e4b668f471ef887135b;hp=29aed953721c6242636c119e975c22a26899909c;hpb=09bc0414c91ebabb67c7fe200549044a1854e199;p=modules%2Fsmesh.git diff --git a/src/SMESHUtils/SMESH_Offset.cxx b/src/SMESHUtils/SMESH_Offset.cxx index 29aed9537..34e3c9d26 100644 --- a/src/SMESHUtils/SMESH_Offset.cxx +++ b/src/SMESHUtils/SMESH_Offset.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -141,11 +141,11 @@ namespace EdgeLoop() : SMDS_PolygonalFaceOfNodes( std::vector() ) {} void Clear() { myLinks.clear(); myIsBndConnected = false; myHasPending = false; } bool SetConnected() { bool was = myIsBndConnected; myIsBndConnected = true; return !was; } - bool Contains( const SMDS_MeshNode* n ) const + size_t Contains( const SMDS_MeshNode* n ) const { for ( size_t i = 0; i < myLinks.size(); ++i ) - if ( myLinks[i]->myNode1 == n ) return true; - return false; + if ( myLinks[i]->myNode1 == n ) return i + 1; + return 0; } virtual int NbNodes() const { return myLinks.size(); } virtual SMDS_ElemIteratorPtr nodesIterator() const @@ -224,6 +224,24 @@ namespace myLoopOfEdge[ Index( *loop->myLinks[ iE ] )] = 0; loop->Clear(); } + void Join( EdgeLoop& loop1, size_t iAfterConcact, + EdgeLoop& loop2, size_t iFromEdge2 ) + { + std::vector< const EdgePart* > linksAfterContact( loop1.myLinks.begin() + iAfterConcact, + loop1.myLinks.end() ); + loop1.myLinks.reserve( loop2.myLinks.size() + loop1.myLinks.size() ); + loop1.myLinks.resize( iAfterConcact ); + loop1.myLinks.insert( loop1.myLinks.end(), + loop2.myLinks.begin() + iFromEdge2, loop2.myLinks.end() ); + loop1.myLinks.insert( loop1.myLinks.end(), + loop2.myLinks.begin(), loop2.myLinks.begin() + iFromEdge2 ); + loop1.myLinks.insert( loop1.myLinks.end(), + linksAfterContact.begin(), linksAfterContact.end() ); + loop1.myIsBndConnected = loop2.myIsBndConnected; + loop2.Clear(); + for ( size_t iE = 0; iE < loop1.myLinks.size(); ++iE ) + myLoopOfEdge[ Index( *loop1.myLinks[ iE ] )] = & loop1; + } size_t Index( const EdgePart& edge ) const { return &edge - myEdge0; } EdgeLoop* GetLoopOf( const EdgePart* edge ) { return myLoopOfEdge[ Index( *edge )]; } }; @@ -741,10 +759,7 @@ namespace SMESH_MeshAlgos const double theSign, const bool theOptimize ); - //! Cut a face by planes, whose normals point to parts to keep - bool CutByPlanes(const SMDS_MeshElement* face, - const std::vector< gp_Ax1 > & planes, - std::vector< SMESH_NodeXYZ > & newConnectivity ); + void IntersectNewEdges( const CutFace& theCFace ); private: @@ -797,7 +812,6 @@ namespace SMESH_MeshAlgos bool & isCollinear ); bool intersectEdgeEdge( int iE1, int iE2, IntPoint2D& intPoint ); bool isPointInTriangle( const gp_XYZ& p, const std::vector< SMESH_NodeXYZ >& nodes ); - void intersectNewEdges( const CutFace& theCFace ); const SMDS_MeshNode* createNode( const gp_XYZ& p ); }; @@ -1644,7 +1658,7 @@ namespace SMESH_MeshAlgos */ //================================================================================ - void Intersector::Algo::intersectNewEdges( const CutFace& cf ) + void Intersector::Algo::IntersectNewEdges( const CutFace& cf ) { IntPoint2D intPoint; @@ -1841,7 +1855,7 @@ namespace SMESH_MeshAlgos } } if ( cf.myLinks.size() >= limit ) - throw SALOME_Exception( "Infinite loop in Intersector::Algo::intersectNewEdges()" ); + throw SALOME_Exception( "Infinite loop in Intersector::Algo::IntersectNewEdges()" ); } ++i1; // each internal edge encounters twice } @@ -1895,7 +1909,7 @@ namespace SMESH_MeshAlgos { const CutFace& cf = *cutFacesIt; cf.ReplaceNodes( myRemove2KeepNodes ); - intersectNewEdges( cf ); + IntersectNewEdges( cf ); } // make new faces @@ -1930,7 +1944,7 @@ namespace SMESH_MeshAlgos // avoid loops that are not connected to boundary edges of cf.myInitFace if ( cf.RemoveInternalLoops( loopSet )) { - intersectNewEdges( cf ); + IntersectNewEdges( cf ); cf.MakeLoops( loopSet, normal ); } // erase loops that are cut off by face intersections @@ -2210,6 +2224,10 @@ namespace SMESH_MeshAlgos theNewFaceConnectivity.push_back( facePoints ); break; } + + // intersect cut lines + algo.IntersectNewEdges( cf ); + // form loops of new faces EdgeLoopSet loopSet; cf.MakeLoops( loopSet, normals[ faceToCut->GetID() ]); @@ -2373,8 +2391,9 @@ namespace // if ( !myLinks[i].IsInternal() ) // myLinks[ i ].myFace = cutterFace; // else - myLinks[ i ].ReplaceCoplanar( newEdge ); - myLinks[ i+1 ].ReplaceCoplanar( newEdge ); + myLinks[ i ].ReplaceCoplanar( newEdge ); + if ( myLinks[i].IsInternal() && i+1 < myLinks.size() ) + myLinks[ i+1 ].ReplaceCoplanar( newEdge ); return; } i += myLinks[i].IsInternal(); @@ -2558,7 +2577,8 @@ namespace //================================================================================ /*! * \brief Remove loops that are not connected to boundary edges of myFace by - * adding edges connecting these loops to the boundary + * adding edges connecting these loops to the boundary. + * Such loops must be removed as they form polygons with ring topology. */ //================================================================================ @@ -2607,14 +2627,49 @@ namespace while ( prevNbReached < nbReachedLoops ); - // add links connecting internal loops with the boundary ones for ( size_t iL = 0; iL < theLoops.myNbLoops; ++iL ) { EdgeLoop& loop = theLoops.myLoops[ iL ]; - if ( loop.myIsBndConnected ) + if ( loop.myIsBndConnected || loop.myLinks.size() == 0 ) continue; + if ( loop.myHasPending ) + { + // try to join the loop to another one, with which it contacts at a node + + // look for a node where the loop reverses + const EdgePart* edgePrev = loop.myLinks.back(); + for ( size_t iE = 0; iE < loop.myLinks.size(); edgePrev = loop.myLinks[ iE++ ] ) + { + if ( !edgePrev->IsTwin( *loop.myLinks[ iE ])) + continue; + const SMDS_MeshNode* reverseNode = edgePrev->myNode2; + + // look for a loop including reverseNode + size_t iContactEdge2; // index(+1) of edge starting at reverseNode + for ( size_t iL2 = 0; iL2 < theLoops.myNbLoops; ++iL2 ) + { + if ( iL == iL2 ) + continue; + EdgeLoop& loop2 = theLoops.myLoops[ iL2 ]; + if ( ! ( iContactEdge2 = loop2.Contains( reverseNode ))) + continue; + + // insert loop2 into the loop + theLoops.Join( loop, iE, loop2, iContactEdge2 - 1 ); + break; + } + if ( loop.myIsBndConnected ) + break; + } + + if ( loop.myIsBndConnected ) + continue; + } + + // add links connecting internal loops with the boundary ones + // find a pair of closest nodes const SMDS_MeshNode *closestNode1, *closestNode2; double minDist = 1e100; @@ -2689,7 +2744,7 @@ namespace while ( !theLoops.AllEdgesUsed() ) { - theLoops.AddNewLoop(); + EdgeLoop& loop = theLoops.AddNewLoop(); // add 1st edge to a new loop size_t i1; @@ -2720,7 +2775,7 @@ namespace // choose among candidates if ( theLoops.myCandidates.size() == 0 ) { - theLoops.GetLoopOf( lastEdge )->myHasPending = true; + loop.myHasPending = bool( twinEdge ); lastEdge = twinEdge; } else if ( theLoops.myCandidates.size() == 1 ) @@ -2751,6 +2806,10 @@ namespace } while ( lastNode != firstNode ); + + if ( twinEdge == & myLinks[ i1 ]) + loop.myHasPending = true; + } // while ( !theLoops.AllEdgesUsed() ) return;