+ if ( SMESH_Algo::IsContinuous( ePrev, *edge ))
+ contVV.Add( SMESH_MesherHelper::IthVertex( 0, *edge ));
+ ePrev = *edge;
+ }
+ }
+ // make edges start from a non-continues VERTEX
+ if ( 1 < contVV.Extent() && contVV.Extent() < nbEdges )
+ {
+ while ( contVV.Contains( SMESH_MesherHelper::IthVertex( 0, edges.front() )))
+ edges.splice( edges.end(), edges, edges.begin() );
+ }
+
+ // make face sides
+ TSideVector sides;
+ while ( !edges.empty() )
+ {
+ list< TopoDS_Edge > sideEdges;
+ sideEdges.splice( sideEdges.end(), edges, edges.begin() );
+ while ( !edges.empty() &&
+ contVV.Contains( SMESH_MesherHelper::IthVertex( 0, edges.front() )))
+ sideEdges.splice( sideEdges.end(), edges, edges.begin() );
+
+ StdMeshers_FaceSidePtr side;
+ if ( aMesh )
+ side = StdMeshers_FaceSide::New( face, sideEdges, aMesh,
+ /*isFwd=*/true, /*skipMedium=*/ true, helper );
+ sides.push_back( side );
+ }
+
+ if ( !aMesh ) // call from IsApplicable()
+ return sides.size();
+
+ if ( sides.size() > 3 )
+ return sides.size();
+
+ if ( nbWire == 2 && (( sides.size() != 2 ) ||
+ ( sides[0]->IsClosed() && sides[1]->IsClosed() ) ||
+ ( !sides[0]->IsClosed() && !sides[1]->IsClosed() )))
+ return -1;
+
+ // detect an elliptic side
+
+ if ( sides.size() == 1 )
+ {
+ aCircSide = sides[0];
+ return sides.size();
+ }
+
+ // sort sides by deviation from a straight line
+ multimap< double, int > deviation2sideInd;
+ const double nbSamples = 7;
+ for ( size_t iS = 0; iS < sides.size(); ++iS )
+ {
+ gp_Pnt pf = BRep_Tool::Pnt( sides[iS]->FirstVertex() );
+ gp_Pnt pl = BRep_Tool::Pnt( sides[iS]->LastVertex() );
+ gp_Vec v1( pf, pl );
+ double v1Len = v1.Magnitude();
+ if ( v1Len < std::numeric_limits< double >::min() )
+ {
+ deviation2sideInd.insert( make_pair( sides[iS]->Length(), iS )); // the side seems closed
+ continue;
+ }
+ double devia = 0;
+ for ( int i = 0; i < nbSamples; ++i )
+ {
+ gp_Pnt pi( sides[iS]->Value3d(( i + 1 ) / nbSamples ));
+ gp_Vec vi( pf, pi );
+ double h = 0.5 * v1.Crossed( vi ).Magnitude() / v1Len;
+ devia = Max( devia, h );
+ }
+ deviation2sideInd.insert( make_pair( devia, iS ));
+ }
+ double maxDevi = deviation2sideInd.rbegin()->first;
+ if ( maxDevi < 1e-7 && sides.size() == 3 )
+ {
+ // a triangle FACE; use a side with the most outstanding length as an elliptic one
+ deviation2sideInd.clear();
+ multimap< double, int > len2sideInd;
+ for ( size_t iS = 0; iS < sides.size(); ++iS )
+ len2sideInd.insert( make_pair( sides[iS]->Length(), iS ));
+
+ multimap< double, int >::iterator l2i = len2sideInd.begin();
+ double len0 = l2i->first;
+ double len1 = (++l2i)->first;
+ double len2 = (++l2i)->first;
+ if ( len1 - len0 > len2 - len1 )
+ deviation2sideInd.insert( std::make_pair( 0., len2sideInd.begin()->second ));
+ else
+ deviation2sideInd.insert( std::make_pair( 0., len2sideInd.rbegin()->second ));
+ }
+
+ double minDevi = deviation2sideInd.begin()->first;
+ int iMinCurv = deviation2sideInd.begin()->second;
+ if ( sides.size() == 3 && degenVV.Size() == 1 &&
+ minDevi / sides[ iMinCurv ]->Length() > 1e-3 )
+ {
+ // a triangle with curved sides and a degenerated EDGE (IPAL54585);
+ // use a side opposite to the degenerated EDGE as an elliptic one
+ for ( size_t iS = 0; iS < sides.size(); ++iS )
+ if ( degenVV.Contains( sides[ iS ]->FirstVertex() ))
+ {
+ deviation2sideInd.clear();
+ deviation2sideInd.insert( std::make_pair( 0.,( iS + 1 ) % sides.size() ));
+ break;