bos #20643 EDF 22805 - Pb Viscous Layer

Fix an issue with periodic FACEs with layers
This commit is contained in:
eap 2021-07-22 14:18:27 +03:00
parent 88ff35ddd4
commit 2a0f82c609
3 changed files with 135 additions and 66 deletions

View File

@ -1068,6 +1068,7 @@ bool SMESH_2D_Algo::FixInternalNodes(const SMESH_ProxyMesh& mesh,
return false; return false;
SMESH_MesherHelper helper( *mesh.GetMesh() ); SMESH_MesherHelper helper( *mesh.GetMesh() );
helper.SetSubShape( face );
// get all faces from a proxy sub-mesh // get all faces from a proxy sub-mesh
typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TIterator; typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TIterator;
@ -1144,7 +1145,7 @@ bool SMESH_2D_Algo::FixInternalNodes(const SMESH_ProxyMesh& mesh,
{ {
++iRow1, ++iRow2; ++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], if (( quad = SMESH_MeshAlgos::FindFaceInSet( nodeRows[iRow1][0],
nodeRows[iRow1][1], nodeRows[iRow1][1],
allFaces, /*avoid=*/firstRowQuads, 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 // get params of the first (bottom) and last (top) node rows
UVPtStructVec uvB( nodeRows[0].size() ), uvT( nodeRows[0].size() ); 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 ) for ( int isBot = 0; isBot < 2; ++isBot )
{ {
iRow1 = isBot ? 0 : nodeRows.size()-1;
iRow2 = isBot ? 1 : nodeRows.size()-2;
UVPtStructVec & uvps = isBot ? uvB : uvT; UVPtStructVec & uvps = isBot ? uvB : uvT;
vector< const SMDS_MeshNode* >& nodes = nodeRows[ isBot ? 0 : nodeRows.size()-1 ]; vector< const SMDS_MeshNode* >& nodes = nodeRows[ iRow1 ];
for ( size_t i = 0; i < nodes.size(); ++i ) const size_t rowLen = nodes.size();
for ( size_t i = 0; i < rowLen; ++i )
{ {
uvps[i].node = nodes[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; 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) // calculate x (normalized param)
for ( size_t i = 1; i < nodes.size(); ++i ) 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() ); UVPtStructVec uvL( nodeRows.size() ), uvR( nodeRows.size() );
for ( int isLeft = 0; isLeft < 2; ++isLeft ) for ( int isLeft = 0; isLeft < 2; ++isLeft )
{ {
UVPtStructVec & uvps = isLeft ? uvL : uvR; UVPtStructVec & uvps = isLeft ? uvL : uvR;
const int iCol = isLeft ? 0 : nodeRows[0].size() - 1; const int iCol1 = isLeft ? 0 : nodeRows[0].size() - 1;
for ( size_t i = 0; i < nodeRows.size(); ++i ) 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]; uvps[i].node = nodeRows[i][iCol1];
gp_XY uv = helper.GetNodeUV( face, uvps[i].node );
uvps[i].u = uv.Coord(1);
uvps[i].v = uv.Coord(2);
uvps[i].y = 0; 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) // calculate y (normalized param)
for ( size_t i = 1; i < nodeRows.size(); ++i ) 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 // update node coordinates
SMESHDS_Mesh* meshDS = mesh.GetMeshDS(); SMESHDS_Mesh* meshDS = mesh.GetMeshDS();
Handle(Geom_Surface) S = BRep_Tool::Surface( face ); if ( !isFix3D )
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 p1 ( uvR[ iRow ].u, uvR[ iRow ].v ); Handle(Geom_Surface) S = BRep_Tool::Surface( face );
gp_XY p3 ( uvL[ iRow ].u, uvL[ iRow ].v ); gp_XY a0 ( uvB.front().u, uvB.front().v );
const double y0 = uvL[ iRow ].y; gp_XY a1 ( uvB.back().u, uvB.back().v );
const double y1 = uvR[ iRow ].y; gp_XY a2 ( uvT.back().u, uvT.back().v );
for ( size_t iCol = 1; iCol < nodeRows[0].size()-1; ++iCol ) 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 p1 ( uvR[ iRow ].u, uvR[ iRow ].v );
gp_XY p2 ( uvT[ iCol ].u, uvT[ iCol ].v ); gp_XY p3 ( uvL[ iRow ].u, uvL[ iRow ].v );
const double x0 = uvB[ iCol ].x; const double y0 = uvL[ iRow ].y;
const double x1 = uvT[ iCol ].x; const double y1 = uvR[ iRow ].y;
double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0)); for ( size_t iCol = 1; iCol < nodeRows[0].size()-1; ++iCol )
double y = y0 + x * (y1 - y0); {
gp_XY uv = helper.calcTFI( x, y, a0,a1,a2,a3, p0,p1,p2,p3 ); gp_XY p0 ( uvB[ iCol ].u, uvB[ iCol ].v );
gp_Pnt p = S->Value( uv.Coord(1), uv.Coord(2)); gp_XY p2 ( uvT[ iCol ].u, uvT[ iCol ].v );
const SMDS_MeshNode* n = nodeRows[iRow][iCol]; const double x0 = uvB[ iCol ].x;
meshDS->MoveNode( n, p.X(), p.Y(), p.Z() ); const double x1 = uvT[ iCol ].x;
if ( SMDS_FacePositionPtr pos = n->GetPosition() ) double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0));
pos->SetParameters( uv.Coord(1), uv.Coord(2) ); 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; return true;

View File

@ -658,10 +658,10 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F,
// corresponding EDGE from FACE, get pcurve for this // corresponding EDGE from FACE, get pcurve for this
// EDGE and retrieve value from this pcurve // EDGE and retrieve value from this pcurve
SMDS_EdgePositionPtr epos = pos; SMDS_EdgePositionPtr epos = pos;
const int edgeID = n->getshapeId(); const int edgeID = n->getshapeId();
const TopoDS_Edge& E = TopoDS::Edge( GetMeshDS()->IndexToShape( edgeID )); const TopoDS_Edge& E = TopoDS::Edge( GetMeshDS()->IndexToShape( edgeID ));
double f, l, u = epos->GetUParameter(); 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 )); bool validU = ( !C2d.IsNull() && ( f < u ) && ( u < l ));
if ( validU ) uv = C2d->Value( u ); if ( validU ) uv = C2d->Value( u );
else uv.SetCoord( Precision::Infinite(),0.); else uv.SetCoord( Precision::Infinite(),0.);
@ -769,6 +769,17 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F,
if ( isSeam ) if ( isSeam )
uv = getUVOnSeam( uv, GetNodeUV( F, n2, 0 )); 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 else
@ -2724,33 +2735,30 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2
theParam2ColumnMap.begin()->second.size() == prevNbRows + expectNbRows ); 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 )
{ {
//================================================================================ int nbFacesInSM = 0;
/*! if ( n ) {
* \brief Return true if a node is at a corner of a 2D structured mesh of FACE SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator( SMDSAbs_Face );
*/ while ( fIt->more() )
//================================================================================ nbFacesInSM += faceSM->Contains( fIt->next() );
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;
} }
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(); int nbRemainEdges = nbEdgesInWires.front();
do { do {
TopoDS_Vertex V = IthVertex( 0, edges.front() ); TopoDS_Vertex V = IthVertex( 0, edges.front() );
isCorner = isCornerOfStructure( SMESH_Algo::VertexNode( V, meshDS ), isCorner = IsCornerOfStructure( SMESH_Algo::VertexNode( V, meshDS ),
fSM, faceAnalyser); fSM, faceAnalyser);
if ( !isCorner ) { if ( !isCorner ) {
edges.splice( edges.end(), edges, edges.begin() ); edges.splice( edges.end(), edges, edges.begin() );
@ -2826,7 +2834,7 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM )
for ( ; n != nodes.end(); ++n ) for ( ; n != nodes.end(); ++n )
{ {
++nbEdges; ++nbEdges;
if ( isCornerOfStructure( *n, fSM, faceAnalyser )) { if ( IsCornerOfStructure( *n, fSM, faceAnalyser )) {
nbEdgesInSide.push_back( nbEdges ); nbEdgesInSide.push_back( nbEdges );
nbEdges = 0; nbEdges = 0;
} }

View File

@ -127,6 +127,13 @@ class SMESH_EXPORT SMESH_MesherHelper
*/ */
static bool IsStructured( SMESH_subMesh* faceSM ); 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 * \brief Return true if 2D mesh on FACE is distored
*/ */