From b8fd583be521c12587f81b616251ecd7d1a16994 Mon Sep 17 00:00:00 2001 From: eap Date: Thu, 9 Apr 2015 21:07:54 +0300 Subject: [PATCH] Regression of 21397: EDF SMESH: a quadrangle face mesh can't be projected to a cylinder + 52675: Viscous Layers construction fails with certain hypotheses Fix normal to be well visible from all faces -> thickness reaches 0.0007 --- src/StdMeshers/StdMeshers_ProjectionUtils.cxx | 2 +- src/StdMeshers/StdMeshers_Projection_2D.cxx | 39 +++++- src/StdMeshers/StdMeshers_ViscousLayers.cxx | 123 ++++++++++-------- 3 files changed, 107 insertions(+), 57 deletions(-) diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index 85ecfac3a..443ddc43c 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -1410,7 +1410,7 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, } if ( TopExp::FirstVertex( *edgeIt ).IsSame( TopExp::LastVertex( *edgeIt )) && SMESH_Algo::isDegenerated( *edgeIt )) { - --edgeIt; // skip a degenerated edge (www.salome-platform.org/forum/forum_11/173031193) + --edgeIt; // skip a degenerated edge (test 3D_mesh_Projection_00/A3) } if ( !VV1[1].IsSame( TopExp::FirstVertex( *edgeIt, true ))) { CONT_BAD_RESULT("GetOrderedEdges() failed"); diff --git a/src/StdMeshers/StdMeshers_Projection_2D.cxx b/src/StdMeshers/StdMeshers_Projection_2D.cxx index 2db02b2ce..853875c5d 100644 --- a/src/StdMeshers/StdMeshers_Projection_2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_2D.cxx @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -1183,6 +1184,8 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& // and target faces in the mapper. Thus we select srcV1 so that // GetOrderedEdges() to return EDGEs in a needed order TopoDS_Face tgtFaceBis = tgtFace; + TopTools_MapOfShape checkedVMap( tgtEdges.size() ); + checkedVMap.Add ( srcV1 ); for ( vSrcExp.Next(); vSrcExp.More(); ) { tgtFaceBis.Reverse(); @@ -1191,7 +1194,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& bool ok = true; list< TopoDS_Edge >::iterator edgeS = srcEdges.begin(), edgeT = tgtEdges.begin(); for ( ; edgeS != srcEdges.end() && ok ; ++edgeS, ++edgeT ) - ok = edgeS->IsSame( shape2ShapeMap( *edgeT )); + ok = edgeT->IsSame( shape2ShapeMap( *edgeS, /*isSrc=*/true )); if ( ok ) break; // FOUND! @@ -1199,6 +1202,8 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& if ( reverse ) { vSrcExp.Next(); + while ( vSrcExp.More() && !checkedVMap.Add( vSrcExp.Current() )) + vSrcExp.Next(); } else { @@ -1209,6 +1214,38 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& } } } + // for the case: project to a closed face from a non-closed face w/o vertex assoc; + // avoid projecting to a seam from two EDGEs with different nb nodes on them + // ( test mesh_Projection_2D_01/B1 ) + if ( !_sourceHypo->HasVertexAssociation() && + nbEdgesInWires.front() > 2 && + helper.IsRealSeam( tgtEdges.front() )) + { + TopoDS_Shape srcEdge1 = shape2ShapeMap( tgtEdges.front() ); + list< TopoDS_Edge >::iterator srcEdge2 = + std::find( srcEdges.begin(), srcEdges.end(), srcEdge1); + list< TopoDS_Edge >::iterator srcEdge3 = + std::find( srcEdges.begin(), srcEdges.end(), srcEdge1.Reversed()); + if ( srcEdge2 == srcEdges.end() || srcEdge3 == srcEdges.end() ) // srcEdge1 is not a seam + { + // find srcEdge2 which also will be projected to tgtEdges.front() + for ( srcEdge2 = srcEdges.begin(); srcEdge2 != srcEdges.end(); ++srcEdge2 ) + if ( !srcEdge1.IsSame( *srcEdge2 ) && + tgtEdges.front().IsSame( shape2ShapeMap( *srcEdge2, /*isSrc=*/true ))) + break; + // compare nb nodes on srcEdge1 and srcEdge2 + if ( srcEdge2 != srcEdges.end() ) + { + int nbN1 = 0, nbN2 = 0; + if ( SMESHDS_SubMesh* sm = srcMesh->GetMeshDS()->MeshElements( srcEdge1 )) + nbN1 = sm->NbNodes(); + if ( SMESHDS_SubMesh* sm = srcMesh->GetMeshDS()->MeshElements( *srcEdge2 )) + nbN2 = sm->NbNodes(); + if ( nbN1 != nbN2 ) + srcV1 = helper.IthVertex( 1, srcEdges.front() ); + } + } + } } else if ( nbEdgesInWires.front() == 1 ) { diff --git a/src/StdMeshers/StdMeshers_ViscousLayers.cxx b/src/StdMeshers/StdMeshers_ViscousLayers.cxx index 61df856fe..8167f864a 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers.cxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers.cxx @@ -3239,74 +3239,87 @@ gp_XYZ _ViscousBuilder::getWeigthedNormal( const SMDS_MeshNode* n, } // exclude equal normals - //int nbUniqNorms = nbFaces; - for ( int i = 0; i < nbFaces; ++i ) + int nbUniqNorms = nbFaces; + for ( int i = 0; i < nbFaces; ++i ) { for ( int j = i+1; j < nbFaces; ++j ) if ( fId2Normal[i].second.IsEqual( fId2Normal[j].second, 0.1 )) { fId2Normal[i].second.SetCoord( 0,0,0 ); - //--nbUniqNorms; + --nbUniqNorms; break; } - //if ( nbUniqNorms < 3 ) - { - for ( int i = 0; i < nbFaces; ++i ) - resNorm += fId2Normal[i].second; - return resNorm; } - - double angles[30]; for ( int i = 0; i < nbFaces; ++i ) - { - const TopoDS_Face& F = fId2Normal[i].first; + resNorm += fId2Normal[i].second; - // look for two EDGEs shared by F and other FACEs within fId2Normal - TopoDS_Edge ee[2]; - int nbE = 0; - PShapeIteratorPtr eIt = SMESH_MesherHelper::GetAncestors( V, *_mesh, TopAbs_EDGE ); - while ( const TopoDS_Shape* E = eIt->next() ) - { - if ( !SMESH_MesherHelper::IsSubShape( *E, F )) - continue; - bool isSharedEdge = false; - for ( int j = 0; j < nbFaces && !isSharedEdge; ++j ) - { - if ( i == j ) continue; - const TopoDS_Shape& otherF = fId2Normal[j].first; - isSharedEdge = SMESH_MesherHelper::IsSubShape( *E, otherF ); - } - if ( !isSharedEdge ) - continue; - ee[ nbE ] = TopoDS::Edge( *E ); - ee[ nbE ].Orientation( SMESH_MesherHelper::GetSubShapeOri( F, *E )); - if ( ++nbE == 2 ) - break; - } - - // get an angle between the two EDGEs - angles[i] = 0; - if ( nbE < 1 ) continue; - if ( nbE == 1 ) - { - ee[ 1 ] == ee[ 0 ]; - } - else + // assure that resNorm is visible by every FACE (IPAL0052675) + if ( nbUniqNorms > 3 ) + { + bool change = false; + for ( int nbAttempts = 0; nbAttempts < nbFaces; ++nbAttempts) { - if ( !V.IsSame( SMESH_MesherHelper::IthVertex( 0, ee[ 1 ] ))) - std::swap( ee[0], ee[1] ); + for ( int i = 0; i < nbFaces; ++i ) + if ( resNorm * fId2Normal[i].second < 0.5 ) + { + resNorm += fId2Normal[i].second; + change = true; + } + if ( !change ) break; } - angles[i] = SMESH_MesherHelper::GetAngle( ee[0], ee[1], F, TopoDS::Vertex( V )); } - // compute a weighted normal - double sumAngle = 0; - for ( int i = 0; i < nbFaces; ++i ) - { - angles[i] = ( angles[i] > 2*M_PI ) ? 0 : M_PI - angles[i]; - sumAngle += angles[i]; - } - for ( int i = 0; i < nbFaces; ++i ) - resNorm += angles[i] / sumAngle * fId2Normal[i].second; + // double angles[30]; + // for ( int i = 0; i < nbFaces; ++i ) + // { + // const TopoDS_Face& F = fId2Normal[i].first; + + // // look for two EDGEs shared by F and other FACEs within fId2Normal + // TopoDS_Edge ee[2]; + // int nbE = 0; + // PShapeIteratorPtr eIt = SMESH_MesherHelper::GetAncestors( V, *_mesh, TopAbs_EDGE ); + // while ( const TopoDS_Shape* E = eIt->next() ) + // { + // if ( !SMESH_MesherHelper::IsSubShape( *E, F )) + // continue; + // bool isSharedEdge = false; + // for ( int j = 0; j < nbFaces && !isSharedEdge; ++j ) + // { + // if ( i == j ) continue; + // const TopoDS_Shape& otherF = fId2Normal[j].first; + // isSharedEdge = SMESH_MesherHelper::IsSubShape( *E, otherF ); + // } + // if ( !isSharedEdge ) + // continue; + // ee[ nbE ] = TopoDS::Edge( *E ); + // ee[ nbE ].Orientation( SMESH_MesherHelper::GetSubShapeOri( F, *E )); + // if ( ++nbE == 2 ) + // break; + // } + + // // get an angle between the two EDGEs + // angles[i] = 0; + // if ( nbE < 1 ) continue; + // if ( nbE == 1 ) + // { + // ee[ 1 ] == ee[ 0 ]; + // } + // else + // { + // if ( !V.IsSame( SMESH_MesherHelper::IthVertex( 0, ee[ 1 ] ))) + // std::swap( ee[0], ee[1] ); + // } + // angles[i] = SMESH_MesherHelper::GetAngle( ee[0], ee[1], F, TopoDS::Vertex( V )); + // } + + // // compute a weighted normal + // double sumAngle = 0; + // for ( int i = 0; i < nbFaces; ++i ) + // { + // angles[i] = ( angles[i] > 2*M_PI ) ? 0 : M_PI - angles[i]; + // sumAngle += angles[i]; + // } + // for ( int i = 0; i < nbFaces; ++i ) + // resNorm += angles[i] / sumAngle * fId2Normal[i].second; return resNorm; } -- 2.30.2