From 2a0f82c609854f56378cf5a26d08841cc232d92b Mon Sep 17 00:00:00 2001 From: eap Date: Thu, 22 Jul 2021 14:18:27 +0300 Subject: [PATCH] bos #20643 EDF 22805 - Pb Viscous Layer Fix an issue with periodic FACEs with layers --- src/SMESH/SMESH_Algo.cxx | 126 ++++++++++++++++++++++--------- src/SMESH/SMESH_MesherHelper.cxx | 68 +++++++++-------- src/SMESH/SMESH_MesherHelper.hxx | 7 ++ 3 files changed, 135 insertions(+), 66 deletions(-) diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index cb9cc7489..9575c5881 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -1068,6 +1068,7 @@ bool SMESH_2D_Algo::FixInternalNodes(const SMESH_ProxyMesh& mesh, return false; SMESH_MesherHelper helper( *mesh.GetMesh() ); + helper.SetSubShape( face ); // get all faces from a proxy sub-mesh typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TIterator; @@ -1144,7 +1145,7 @@ bool SMESH_2D_Algo::FixInternalNodes(const SMESH_ProxyMesh& mesh, { ++iRow1, ++iRow2; - // get the first quad in the next face row + // get the first quad in the next face row if (( quad = SMESH_MeshAlgos::FindFaceInSet( nodeRows[iRow1][0], nodeRows[iRow1][1], allFaces, /*avoid=*/firstRowQuads, @@ -1184,17 +1185,28 @@ bool SMESH_2D_Algo::FixInternalNodes(const SMESH_ProxyMesh& mesh, // get params of the first (bottom) and last (top) node rows UVPtStructVec uvB( nodeRows[0].size() ), uvT( nodeRows[0].size() ); + bool uvOk = false, *toCheck = helper.GetPeriodicIndex() ? &uvOk : nullptr; + const bool isFix3D = helper.HasDegeneratedEdges(); for ( int isBot = 0; isBot < 2; ++isBot ) { + iRow1 = isBot ? 0 : nodeRows.size()-1; + iRow2 = isBot ? 1 : nodeRows.size()-2; UVPtStructVec & uvps = isBot ? uvB : uvT; - vector< const SMDS_MeshNode* >& nodes = nodeRows[ isBot ? 0 : nodeRows.size()-1 ]; - for ( size_t i = 0; i < nodes.size(); ++i ) + vector< const SMDS_MeshNode* >& nodes = nodeRows[ iRow1 ]; + const size_t rowLen = nodes.size(); + for ( size_t i = 0; i < rowLen; ++i ) { uvps[i].node = nodes[i]; - gp_XY uv = helper.GetNodeUV( face, uvps[i].node ); - uvps[i].u = uv.Coord(1); - uvps[i].v = uv.Coord(2); uvps[i].x = 0; + if ( !isFix3D ) + { + size_t i2 = i; + if ( i == 0 ) i2 = 1; + if ( i == rowLen - 1 ) i2 = rowLen - 2; + gp_XY uv = helper.GetNodeUV( face, uvps[i].node, nodeRows[iRow2][i2], toCheck ); + uvps[i].u = uv.Coord(1); + uvps[i].v = uv.Coord(2); + } } // calculate x (normalized param) for ( size_t i = 1; i < nodes.size(); ++i ) @@ -1207,15 +1219,23 @@ bool SMESH_2D_Algo::FixInternalNodes(const SMESH_ProxyMesh& mesh, UVPtStructVec uvL( nodeRows.size() ), uvR( nodeRows.size() ); for ( int isLeft = 0; isLeft < 2; ++isLeft ) { - UVPtStructVec & uvps = isLeft ? uvL : uvR; - const int iCol = isLeft ? 0 : nodeRows[0].size() - 1; - for ( size_t i = 0; i < nodeRows.size(); ++i ) + UVPtStructVec & uvps = isLeft ? uvL : uvR; + const int iCol1 = isLeft ? 0 : nodeRows[0].size() - 1; + const int iCol2 = isLeft ? 1 : nodeRows[0].size() - 2; + const size_t nbRows = nodeRows.size(); + for ( size_t i = 0; i < nbRows; ++i ) { - uvps[i].node = nodeRows[i][iCol]; - gp_XY uv = helper.GetNodeUV( face, uvps[i].node ); - uvps[i].u = uv.Coord(1); - uvps[i].v = uv.Coord(2); + uvps[i].node = nodeRows[i][iCol1]; uvps[i].y = 0; + if ( !isFix3D ) + { + size_t i2 = i; + if ( i == 0 ) i2 = 1; + if ( i == nbRows - 1 ) i2 = nbRows - 2; + gp_XY uv = helper.GetNodeUV( face, uvps[i].node, nodeRows[i2][iCol2], toCheck ); + uvps[i].u = uv.Coord(1); + uvps[i].v = uv.Coord(2); + } } // calculate y (normalized param) for ( size_t i = 1; i < nodeRows.size(); ++i ) @@ -1226,31 +1246,65 @@ bool SMESH_2D_Algo::FixInternalNodes(const SMESH_ProxyMesh& mesh, // update node coordinates SMESHDS_Mesh* meshDS = mesh.GetMeshDS(); - Handle(Geom_Surface) S = BRep_Tool::Surface( face ); - gp_XY a0 ( uvB.front().u, uvB.front().v ); - gp_XY a1 ( uvB.back().u, uvB.back().v ); - gp_XY a2 ( uvT.back().u, uvT.back().v ); - gp_XY a3 ( uvT.front().u, uvT.front().v ); - for ( size_t iRow = 1; iRow < nodeRows.size()-1; ++iRow ) + if ( !isFix3D ) { - gp_XY p1 ( uvR[ iRow ].u, uvR[ iRow ].v ); - gp_XY p3 ( uvL[ iRow ].u, uvL[ iRow ].v ); - const double y0 = uvL[ iRow ].y; - const double y1 = uvR[ iRow ].y; - for ( size_t iCol = 1; iCol < nodeRows[0].size()-1; ++iCol ) + Handle(Geom_Surface) S = BRep_Tool::Surface( face ); + gp_XY a0 ( uvB.front().u, uvB.front().v ); + gp_XY a1 ( uvB.back().u, uvB.back().v ); + gp_XY a2 ( uvT.back().u, uvT.back().v ); + gp_XY a3 ( uvT.front().u, uvT.front().v ); + for ( size_t iRow = 1; iRow < nodeRows.size()-1; ++iRow ) { - gp_XY p0 ( uvB[ iCol ].u, uvB[ iCol ].v ); - gp_XY p2 ( uvT[ iCol ].u, uvT[ iCol ].v ); - const double x0 = uvB[ iCol ].x; - const double x1 = uvT[ iCol ].x; - double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0)); - double y = y0 + x * (y1 - y0); - gp_XY uv = helper.calcTFI( x, y, a0,a1,a2,a3, p0,p1,p2,p3 ); - gp_Pnt p = S->Value( uv.Coord(1), uv.Coord(2)); - const SMDS_MeshNode* n = nodeRows[iRow][iCol]; - meshDS->MoveNode( n, p.X(), p.Y(), p.Z() ); - if ( SMDS_FacePositionPtr pos = n->GetPosition() ) - pos->SetParameters( uv.Coord(1), uv.Coord(2) ); + gp_XY p1 ( uvR[ iRow ].u, uvR[ iRow ].v ); + gp_XY p3 ( uvL[ iRow ].u, uvL[ iRow ].v ); + const double y0 = uvL[ iRow ].y; + const double y1 = uvR[ iRow ].y; + for ( size_t iCol = 1; iCol < nodeRows[0].size()-1; ++iCol ) + { + gp_XY p0 ( uvB[ iCol ].u, uvB[ iCol ].v ); + gp_XY p2 ( uvT[ iCol ].u, uvT[ iCol ].v ); + const double x0 = uvB[ iCol ].x; + const double x1 = uvT[ iCol ].x; + double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0)); + double y = y0 + x * (y1 - y0); + gp_XY uv = helper.calcTFI( x, y, a0,a1,a2,a3, p0,p1,p2,p3 ); + gp_Pnt p = S->Value( uv.Coord(1), uv.Coord(2)); + const SMDS_MeshNode* n = nodeRows[iRow][iCol]; + meshDS->MoveNode( n, p.X(), p.Y(), p.Z() ); + if ( SMDS_FacePositionPtr pos = n->GetPosition() ) + pos->SetParameters( uv.Coord(1), uv.Coord(2) ); + } + } + } + else + { + Handle(ShapeAnalysis_Surface) S = helper.GetSurface( face ); + SMESH_NodeXYZ a0 ( uvB.front().node ); + SMESH_NodeXYZ a1 ( uvB.back().node ); + SMESH_NodeXYZ a2 ( uvT.back().node ); + SMESH_NodeXYZ a3 ( uvT.front().node ); + for ( size_t iRow = 1; iRow < nodeRows.size()-1; ++iRow ) + { + SMESH_NodeXYZ p1 ( uvR[ iRow ].node ); + SMESH_NodeXYZ p3 ( uvL[ iRow ].node ); + const double y0 = uvL[ iRow ].y; + const double y1 = uvR[ iRow ].y; + for ( size_t iCol = 1; iCol < nodeRows[0].size()-1; ++iCol ) + { + SMESH_NodeXYZ p0 ( uvB[ iCol ].node ); + SMESH_NodeXYZ p2 ( uvT[ iCol ].node ); + const double x0 = uvB[ iCol ].x; + const double x1 = uvT[ iCol ].x; + double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0)); + double y = y0 + x * (y1 - y0); + gp_Pnt p = helper.calcTFI( x, y, a0,a1,a2,a3, p0,p1,p2,p3 ); + gp_Pnt2d uv = S->ValueOfUV( p, Precision::Confusion() ); + p = S->Value( uv ); + const SMDS_MeshNode* n = nodeRows[iRow][iCol]; + meshDS->MoveNode( n, p.X(), p.Y(), p.Z() ); + if ( SMDS_FacePositionPtr pos = n->GetPosition() ) + pos->SetParameters( uv.Coord(1), uv.Coord(2) ); + } } } return true; diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 3b5483b13..1dcc5b064 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -658,10 +658,10 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, // corresponding EDGE from FACE, get pcurve for this // EDGE and retrieve value from this pcurve SMDS_EdgePositionPtr epos = pos; - const int edgeID = n->getshapeId(); - const TopoDS_Edge& E = TopoDS::Edge( GetMeshDS()->IndexToShape( edgeID )); + const int edgeID = n->getshapeId(); + const TopoDS_Edge& E = TopoDS::Edge( GetMeshDS()->IndexToShape( edgeID )); double f, l, u = epos->GetUParameter(); - Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( E, F, f, l ); + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( E, F, f, l ); bool validU = ( !C2d.IsNull() && ( f < u ) && ( u < l )); if ( validU ) uv = C2d->Value( u ); else uv.SetCoord( Precision::Infinite(),0.); @@ -769,6 +769,17 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, if ( isSeam ) uv = getUVOnSeam( uv, GetNodeUV( F, n2, 0 )); } + else if ( myParIndex && n2 ) + { + gp_Pnt2d oldUV = uv; + gp_Pnt2d uv2 = GetNodeUV( F, n2, 0 ); + if ( myParIndex & 1 ) + uv.SetX( uv.X() + ShapeAnalysis::AdjustToPeriod( uv.X(), myPar1[0], myPar2[0])); + if ( myParIndex & 2 ) + uv.SetY( uv.Y() + ShapeAnalysis::AdjustToPeriod( uv.Y(), myPar1[1], myPar2[1])); + if ( uv.SquareDistance( uv2 ) > oldUV.SquareDistance( uv2 )) + uv = oldUV; + } } } else @@ -2724,33 +2735,30 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2 theParam2ColumnMap.begin()->second.size() == prevNbRows + expectNbRows ); } -namespace +//================================================================================ +/*! + * \brief Return true if a node is at a corner of a 2D structured mesh of FACE + */ +//================================================================================ + +bool SMESH_MesherHelper::IsCornerOfStructure( const SMDS_MeshNode* n, + const SMESHDS_SubMesh* faceSM, + SMESH_MesherHelper& faceAnalyser ) { - //================================================================================ - /*! - * \brief Return true if a node is at a corner of a 2D structured mesh of FACE - */ - //================================================================================ - - bool isCornerOfStructure( const SMDS_MeshNode* n, - const SMESHDS_SubMesh* faceSM, - SMESH_MesherHelper& faceAnalyser ) - { - int nbFacesInSM = 0; - if ( n ) { - SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator( SMDSAbs_Face ); - while ( fIt->more() ) - nbFacesInSM += faceSM->Contains( fIt->next() ); - } - if ( nbFacesInSM == 1 ) - return true; - - if ( nbFacesInSM == 2 && n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ) - { - return faceAnalyser.IsRealSeam( n->getshapeId() ); - } - return false; + int nbFacesInSM = 0; + if ( n ) { + SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator( SMDSAbs_Face ); + while ( fIt->more() ) + nbFacesInSM += faceSM->Contains( fIt->next() ); } + if ( nbFacesInSM == 1 ) + return true; + + if ( nbFacesInSM == 2 && n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ) + { + return faceAnalyser.IsRealSeam( n->getshapeId() ); + } + return false; } //======================================================================= @@ -2785,7 +2793,7 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM ) int nbRemainEdges = nbEdgesInWires.front(); do { TopoDS_Vertex V = IthVertex( 0, edges.front() ); - isCorner = isCornerOfStructure( SMESH_Algo::VertexNode( V, meshDS ), + isCorner = IsCornerOfStructure( SMESH_Algo::VertexNode( V, meshDS ), fSM, faceAnalyser); if ( !isCorner ) { edges.splice( edges.end(), edges, edges.begin() ); @@ -2826,7 +2834,7 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM ) for ( ; n != nodes.end(); ++n ) { ++nbEdges; - if ( isCornerOfStructure( *n, fSM, faceAnalyser )) { + if ( IsCornerOfStructure( *n, fSM, faceAnalyser )) { nbEdgesInSide.push_back( nbEdges ); nbEdges = 0; } diff --git a/src/SMESH/SMESH_MesherHelper.hxx b/src/SMESH/SMESH_MesherHelper.hxx index d48318877..82d242ec2 100644 --- a/src/SMESH/SMESH_MesherHelper.hxx +++ b/src/SMESH/SMESH_MesherHelper.hxx @@ -127,6 +127,13 @@ class SMESH_EXPORT SMESH_MesherHelper */ static bool IsStructured( SMESH_subMesh* faceSM ); + /*! + * \brief Return true if a node is at a corner of a 2D structured mesh of FACE + */ + static bool IsCornerOfStructure( const SMDS_MeshNode* n, + const SMESHDS_SubMesh* faceSM, + SMESH_MesherHelper& faceAnalyser ); + /*! * \brief Return true if 2D mesh on FACE is distored */