+//================================================================================
+/*!
+ * Fill data._simplexTestEdges. These _LayerEdge's are used to stop inflation
+ * in the case where there are no _LayerEdge's on a curved convex FACE,
+ * as e.g. on a fillet surface with no internal nodes - issue 22580,
+ * so that collision of viscous internal faces is not detected by check of
+ * intersection of _LayerEdge's with the viscous internal faces.
+ */
+//================================================================================
+
+void _ViscousBuilder::findSimplexTestEdges( _SolidData& data,
+ vector< vector<_LayerEdge*> >& edgesByGeom)
+{
+ data._simplexTestEdges.clear();
+
+ SMESH_MesherHelper helper( *_mesh );
+
+ vector< vector<_LayerEdge*> * > ledgesOnEdges;
+ set< const SMDS_MeshNode* > usedNodes;
+
+ const double minCurvature = 1. / data._hyp->GetTotalThickness();
+
+ for ( size_t iS = 0; iS < edgesByGeom.size(); ++iS )
+ {
+ // look for a FACE with layers and w/o _LayerEdge's
+ const vector<_LayerEdge*>& eS = edgesByGeom[iS];
+ if ( !eS.empty() ) continue;
+ const TopoDS_Shape& S = getMeshDS()->IndexToShape( iS );
+ if ( S.IsNull() || S.ShapeType() != TopAbs_FACE ) continue;
+ if ( data._ignoreFaceIds.count( iS )) continue;
+
+ const TopoDS_Face& F = TopoDS::Face( S );
+
+ // look for _LayerEdge's on EDGEs with null _sWOL
+ ledgesOnEdges.clear();
+ TopExp_Explorer eExp( F, TopAbs_EDGE );
+ for ( ; eExp.More(); eExp.Next() )
+ {
+ TGeomID iE = getMeshDS()->ShapeToIndex( eExp.Current() );
+ vector<_LayerEdge*>& eE = edgesByGeom[iE];
+ if ( !eE.empty() && eE[0]->_sWOL.IsNull() )
+ ledgesOnEdges.push_back( & eE );
+ }
+ if ( ledgesOnEdges.empty() ) continue;
+
+ // check FACE convexity
+ const _LayerEdge* le = ledgesOnEdges[0]->back();
+ gp_XY uv = helper.GetNodeUV( F, le->_nodes[0] );
+ BRepAdaptor_Surface surf( F );
+ BRepLProp_SLProps surfProp( surf, uv.X(), uv.Y(), 2, 1e-6 );
+ if ( !surfProp.IsCurvatureDefined() )
+ continue;
+ double surfCurvature = Max( Abs( surfProp.MaxCurvature() ),
+ Abs( surfProp.MinCurvature() ));
+ if ( surfCurvature < minCurvature )
+ continue;
+ gp_Dir minDir, maxDir;
+ surfProp.CurvatureDirections( maxDir, minDir );
+ if ( F.Orientation() == TopAbs_REVERSED ) {
+ maxDir.Reverse(); minDir.Reverse();
+ }
+ const gp_XYZ& inDir = le->_normal;
+ if ( inDir * maxDir.XYZ() < 0 &&
+ inDir * minDir.XYZ() < 0 )
+ continue;
+
+ limitStepSize( data, 0.9 / surfCurvature );
+
+ // add _simplices to the _LayerEdge's
+ for ( size_t iE = 0; iE < ledgesOnEdges.size(); ++iE )
+ {
+ const vector<_LayerEdge*>& ledges = *ledgesOnEdges[iE];
+ for ( size_t iLE = 0; iLE < ledges.size(); ++iLE )
+ {
+ _LayerEdge* ledge = ledges[iLE];
+ const SMDS_MeshNode* srcNode = ledge->_nodes[0];
+ if ( !usedNodes.insert( srcNode ).second ) continue;
+
+ getSimplices( srcNode, ledge->_simplices, data._ignoreFaceIds, &data );
+ for ( size_t i = 0; i < ledge->_simplices.size(); ++i )
+ {
+ usedNodes.insert( ledge->_simplices[i]._nPrev );
+ usedNodes.insert( ledge->_simplices[i]._nNext );
+ }
+ data._simplexTestEdges.push_back( ledge );
+ }
+ }
+ }
+}
+