From 020e13d9f10c98002d89a887667ad81e81dd28e4 Mon Sep 17 00:00:00 2001 From: eap Date: Tue, 23 May 2017 20:19:15 +0300 Subject: [PATCH] Fix unstable failure of SALOME_TESTS/Grids/smesh/bugs_05/F0 --- src/SMESH/SMESH_Algo.cxx | 39 +++++++++++++++----------- src/SMESH/SMESH_MeshEditor.cxx | 18 ++++++------ src/SMESHUtils/SMESH_Delaunay.cxx | 23 +++++++++------ src/StdMeshers/StdMeshers_FaceSide.cxx | 2 +- src/StdMeshers/StdMeshers_Prism_3D.cxx | 13 +++++---- src/StdMeshers/StdMeshers_Prism_3D.hxx | 2 +- 6 files changed, 54 insertions(+), 43 deletions(-) diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index bb21f5c0e..4e4002ee3 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -553,28 +553,35 @@ bool SMESH_Algo::IsStraight( const TopoDS_Edge & E, case GeomAbs_Hyperbola: case GeomAbs_Parabola: return false; - // case GeomAbs_BezierCurve: - // case GeomAbs_BSplineCurve: - // case GeomAbs_OtherCurve: + // case GeomAbs_BezierCurve: + // case GeomAbs_BSplineCurve: + // case GeomAbs_OtherCurve: default:; } - const double f = curve.FirstParameter(); - const double l = curve.LastParameter(); - const gp_Pnt pf = curve.Value( f ); - const gp_Pnt pl = curve.Value( l ); - const gp_Vec v1( pf, pl ); - const double v1Len = v1.Magnitude(); - if ( v1Len < std::numeric_limits< double >::min() ) + + // evaluate how far from a straight line connecting the curve ends + // stand internal points of the curve + double f = curve.FirstParameter(); + double l = curve.LastParameter(); + gp_Pnt pf = curve.Value( f ); + gp_Pnt pl = curve.Value( l ); + gp_Vec lineVec( pf, pl ); + double lineLen2 = lineVec.SquareMagnitude(); + if ( lineLen2 < std::numeric_limits< double >::min() ) return false; // E seems closed - const double tol = Min( 10 * curve.Tolerance(), v1Len * 1e-2 ); + + double edgeTol = 10 * curve.Tolerance(); + double lenTol2 = lineLen2 * 1e-4; + double tol2 = Min( edgeTol * edgeTol, lenTol2 ); + const double nbSamples = 7; for ( int i = 0; i < nbSamples; ++i ) { - const double r = ( i + 1 ) / nbSamples; - const gp_Pnt pi = curve.Value( f * r + l * ( 1 - r )); - const gp_Vec vi( pf, pi ); - const double h = 0.5 * v1.Crossed( vi ).Magnitude() / v1Len; - if ( h > tol ) + double r = ( i + 1 ) / nbSamples; + gp_Pnt pi = curve.Value( f * r + l * ( 1 - r )); + gp_Vec vi( pf, pi ); + double h2 = lineVec.Crossed( vi ).SquareMagnitude() / lineLen2; + if ( h2 > tol2 ) return false; } return true; diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 1f343b1c4..c477e729e 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -7482,8 +7482,8 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes, } // Remove bad elements, then equal nodes (order important) - Remove( rmElemIds, false ); - Remove( rmNodeIds, true ); + Remove( rmElemIds, /*isNodes=*/false ); + Remove( rmNodeIds, /*isNodes=*/true ); return; } @@ -7553,14 +7553,14 @@ bool SMESH_MeshEditor::applyMerge( const SMDS_MeshElement* elem, toRemove = true; nbResElems = 0; - if ( elem->IsQuadratic() && newElemDefs[0].myType == SMDSAbs_Face && nbNodes > 6 ) + if ( newElemDefs[0].myIsQuad && newElemDefs[0].myType == SMDSAbs_Face && nbNodes > 6 ) { // if corner nodes stick, remove medium nodes between them from uniqueNodes int nbCorners = nbNodes / 2; for ( int iCur = 0; iCur < nbCorners; ++iCur ) { - int iPrev = ( iCur + 1 ) % nbCorners; - if ( curNodes[ iCur ] == curNodes[ iPrev ] ) // corners stick + int iNext = ( iCur + 1 ) % nbCorners; + if ( curNodes[ iCur ] == curNodes[ iNext ] ) // corners stick { int iMedium = iCur + nbCorners; vector< const SMDS_MeshNode* >::iterator i = @@ -7711,11 +7711,9 @@ bool SMESH_MeshEditor::applyMerge( const SMDS_MeshElement* elem, // | | // +---+---+ // 0 7 3 - if (( nbUniqueNodes == 7 && nbRepl == 2 && iRepl[1] != 8 ) && - (( iRepl[0] == 1 && iRepl[1] == 4 && curNodes[1] == curNodes[0] ) || - ( iRepl[0] == 2 && iRepl[1] == 5 && curNodes[2] == curNodes[1] ) || - ( iRepl[0] == 3 && iRepl[1] == 6 && curNodes[3] == curNodes[2] ) || - ( iRepl[0] == 3 && iRepl[1] == 7 && curNodes[3] == curNodes[0] ))) + if ( nbUniqueNodes == 7 && + iRepl[0] < 4 && + ( nbRepl == 1 || iRepl[1] != 8 )) { toRemove = false; } diff --git a/src/SMESHUtils/SMESH_Delaunay.cxx b/src/SMESHUtils/SMESH_Delaunay.cxx index 85f03a65e..e53bfd8fc 100644 --- a/src/SMESHUtils/SMESH_Delaunay.cxx +++ b/src/SMESHUtils/SMESH_Delaunay.cxx @@ -193,16 +193,21 @@ const BRepMesh_Triangle* SMESH_Delaunay::FindTriangle( const gp_XY& nodeUVs[1] = _triaDS->GetNode( nodeIDs[1] ).Coord(); nodeUVs[2] = _triaDS->GetNode( nodeIDs[2] ).Coord(); - SMESH_MeshAlgos::GetBarycentricCoords( uv, - nodeUVs[0], nodeUVs[1], nodeUVs[2], - bc[0], bc[1] ); - if ( bc[0] >= 0 && bc[1] >= 0 && bc[0] + bc[1] <= 1 ) + if ( _triaDS->GetNode( nodeIDs[0] ).Movability() == BRepMesh_Frontier && + _triaDS->GetNode( nodeIDs[1] ).Movability() == BRepMesh_Frontier && + _triaDS->GetNode( nodeIDs[2] ).Movability() == BRepMesh_Frontier ) { - bc[2] = 1 - bc[0] - bc[1]; - triaNodes[0] = nodeIDs[0] - 1; - triaNodes[1] = nodeIDs[1] - 1; - triaNodes[2] = nodeIDs[2] - 1; - return tria; + SMESH_MeshAlgos::GetBarycentricCoords( uv, + nodeUVs[0], nodeUVs[1], nodeUVs[2], + bc[0], bc[1] ); + if ( bc[0] >= 0 && bc[1] >= 0 && bc[0] + bc[1] <= 1 ) + { + bc[2] = 1 - bc[0] - bc[1]; + triaNodes[0] = nodeIDs[0] - 1; + triaNodes[1] = nodeIDs[1] - 1; + triaNodes[2] = nodeIDs[2] - 1; + return tria; + } } // look for a neighbor triangle, which is adjacent to a link intersected diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx index 71677dc1b..b0d36a59c 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.cxx +++ b/src/StdMeshers/StdMeshers_FaceSide.cxx @@ -1251,7 +1251,7 @@ gp_Pnt StdMeshers_FaceSide::Value3d(double U) const // check parametrization of curve if( !myIsUniform[i] ) { - double aLen3dU = r * myEdgeLength[i] * ( myFirst[i]>myLast[i] ? -1. : 1.); + double aLen3dU = r * myEdgeLength[i] * ( myFirst[i] > myLast[i] ? -1. : 1. ); GCPnts_AbscissaPoint AbPnt ( const_cast( myC3dAdaptor[i]), aLen3dU, myFirst[i] ); if( AbPnt.IsDone() ) { diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index 939679f95..ae8ccc430 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -4962,7 +4962,8 @@ bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol, // for each internal column find boundary nodes whose error to use for correction prepareTopBotDelaunay(); - findDelaunayTriangles(); + if ( !findDelaunayTriangles()) + return false; // compute coordinates of internal nodes by projecting (transfroming) src and tgt // nodes towards the central layer @@ -5390,11 +5391,11 @@ void StdMeshers_Sweeper::prepareTopBotDelaunay() //================================================================================ /*! * \brief For each internal node column, find Delaunay triangles including it - * and Barycentric Coordinates withing the triangles. Fill in myTopBotTriangles + * and Barycentric Coordinates within the triangles. Fill in myTopBotTriangles */ //================================================================================ -void StdMeshers_Sweeper::findDelaunayTriangles() +bool StdMeshers_Sweeper::findDelaunayTriangles() { const SMDS_MeshNode *botNode, *topNode; const BRepMesh_Triangle *topTria; @@ -5424,14 +5425,14 @@ void StdMeshers_Sweeper::findDelaunayTriangles() myTopBotTriangles[ colID ] = tbTrias; } -#ifdef _DEBUG_ if ( myBotDelaunay->NbVisitedNodes() < nbInternalNodes ) - throw SALOME_Exception(LOCALIZED("Not all internal nodes found by Delaunay")); -#endif + return false; myBotDelaunay.reset(); myTopDelaunay.reset(); myNodeID2ColID.Clear(); + + return true; } //================================================================================ diff --git a/src/StdMeshers/StdMeshers_Prism_3D.hxx b/src/StdMeshers/StdMeshers_Prism_3D.hxx index da4b055e0..62f0b9a14 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.hxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.hxx @@ -453,7 +453,7 @@ private: TNodeColumn& nodes ); void prepareTopBotDelaunay(); - void findDelaunayTriangles(); + bool findDelaunayTriangles(); std::vector< TZColumn > myZColumns; // Z distribution of boundary nodes