Salome HOME
Dump Puthon extension
[modules/smesh.git] / src / Controls / SMESH_Controls.cxx
index 5559dddeccecd6e14593654a0f5ba0d1207fca85..3350a966e13e11683ec755f1ee08b10ab7285cf7 100644 (file)
 
 #include <set>
 
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepClass_FaceClassifier.hxx>
 #include <BRep_Tool.hxx>
+
+#include <TopAbs.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Iterator.hxx>
+
+#include <Geom_CylindricalSurface.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_Surface.hxx>
+
+#include <Precision.hxx>
+#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_SequenceOfAsciiString.hxx>
+#include <TColgp_Array1OfXYZ.hxx>
+
 #include <gp_Ax3.hxx>
 #include <gp_Cylinder.hxx>
 #include <gp_Dir.hxx>
-#include <gp_Pnt.hxx>
 #include <gp_Pln.hxx>
+#include <gp_Pnt.hxx>
 #include <gp_Vec.hxx>
 #include <gp_XYZ.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom_CylindricalSurface.hxx>
-#include <Precision.hxx>
-#include <TColgp_Array1OfXYZ.hxx>
-#include <TColStd_MapOfInteger.hxx>
-#include <TColStd_SequenceOfAsciiString.hxx>
-#include <TColStd_MapIteratorOfMapOfInteger.hxx>
-#include <TopAbs.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Shape.hxx>
 
 #include "SMDS_Mesh.hxx"
 #include "SMDS_Iterator.hxx"
@@ -49,7 +59,6 @@
 #include "SMDS_QuadraticFaceOfNodes.hxx"
 #include "SMDS_QuadraticEdge.hxx"
 
-
 /*
                             AUXILIARY METHODS
 */
@@ -128,7 +137,7 @@ namespace{
         }
       }
     }
-    int aResult = max ( aResult0, aResult1 );
+    int aResult = std::max ( aResult0, aResult1 );
 
 //     TColStd_MapOfInteger aMap;
 
@@ -354,7 +363,7 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P )
 
   if ( nbNodes == 3 ) {
     // Compute lengths of the sides
-    vector< double > aLen (nbNodes);
+    std::vector< double > aLen (nbNodes);
     for ( int i = 0; i < nbNodes - 1; i++ )
       aLen[ i ] = getDistance( P( i + 1 ), P( i + 2 ) );
     aLen[ nbNodes - 1 ] = getDistance( P( 1 ), P( nbNodes ) );
@@ -374,7 +383,7 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P )
   }
   else if ( nbNodes == 6 ) { // quadratic triangles
     // Compute lengths of the sides
-    vector< double > aLen (3);
+    std::vector< double > aLen (3);
     aLen[0] = getDistance( P(1), P(3) );
     aLen[1] = getDistance( P(3), P(5) );
     aLen[2] = getDistance( P(5), P(1) );
@@ -506,11 +515,11 @@ namespace{
 
   inline double getMaxHeight(double theLen[6])
   {
-    double aHeight = max(theLen[0],theLen[1]);
-    aHeight = max(aHeight,theLen[2]);
-    aHeight = max(aHeight,theLen[3]);
-    aHeight = max(aHeight,theLen[4]);
-    aHeight = max(aHeight,theLen[5]);
+    double aHeight = std::max(theLen[0],theLen[1]);
+    aHeight = std::max(aHeight,theLen[2]);
+    aHeight = std::max(aHeight,theLen[3]);
+    aHeight = std::max(aHeight,theLen[4]);
+    aHeight = std::max(aHeight,theLen[5]);
     return aHeight;
   }
 
@@ -520,7 +529,17 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P )
 {
   double aQuality = 0.0;
   if(myCurrElement->IsPoly()) return aQuality;
+
   int nbNodes = P.size();
+
+  if(myCurrElement->IsQuadratic()) {
+    if(nbNodes==10) nbNodes=4; // quadratic tetrahedron
+    else if(nbNodes==13) nbNodes=5; // quadratic pyramid
+    else if(nbNodes==15) nbNodes=6; // quadratic pentahedron
+    else if(nbNodes==20) nbNodes=8; // quadratic hexahedron
+    else return aQuality;
+  }
+
   switch(nbNodes){
   case 4:{
     double aLen[6] = {
@@ -554,187 +573,188 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P )
     //double aVolume = getVolume(aLen);
     double aHeight = getMaxHeight(aLen);
     static double aCoeff = sqrt(2.0)/12.0;
-    aQuality = aCoeff*aHeight*aSumArea/aVolume;
+    if ( aVolume > DBL_MIN )
+      aQuality = aCoeff*aHeight*aSumArea/aVolume;
     break;
   }
   case 5:{
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 3 ),P( 5 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 3 ),P( 4 ),P( 5 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 4 ),P( 5 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 2 ),P( 3 ),P( 4 ),P( 5 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     break;
   }
   case 6:{
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 4 ),P( 6 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 4 ),P( 3 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 5 ),P( 6 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 5 ),P( 3 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 2 ),P( 5 ),P( 4 ),P( 6 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 2 ),P( 5 ),P( 4 ),P( 3 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     break;
   }
   case 8:{
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 5 ),P( 3 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 5 ),P( 4 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 5 ),P( 7 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 5 ),P( 8 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 6 ),P( 3 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 6 ),P( 4 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 6 ),P( 7 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 6 ),P( 8 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 2 ),P( 6 ),P( 5 ),P( 3 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 2 ),P( 6 ),P( 5 ),P( 4 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 2 ),P( 6 ),P( 5 ),P( 7 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 2 ),P( 6 ),P( 5 ),P( 8 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 3 ),P( 4 ),P( 8 ),P( 1 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 3 ),P( 4 ),P( 8 ),P( 2 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 3 ),P( 4 ),P( 8 ),P( 5 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 3 ),P( 4 ),P( 8 ),P( 6 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 3 ),P( 4 ),P( 7 ),P( 1 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 3 ),P( 4 ),P( 7 ),P( 2 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 3 ),P( 4 ),P( 7 ),P( 5 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 3 ),P( 4 ),P( 7 ),P( 6 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 4 ),P( 8 ),P( 7 ),P( 1 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 4 ),P( 8 ),P( 7 ),P( 2 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 4 ),P( 8 ),P( 7 ),P( 5 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 4 ),P( 8 ),P( 7 ),P( 6 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 4 ),P( 8 ),P( 7 ),P( 2 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 4 ),P( 5 ),P( 8 ),P( 2 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 4 ),P( 5 ),P( 3 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 3 ),P( 6 ),P( 7 ),P( 1 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 2 ),P( 3 ),P( 6 ),P( 4 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 5 ),P( 6 ),P( 8 ),P( 3 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 7 ),P( 8 ),P( 6 ),P( 1 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 1 ),P( 2 ),P( 4 ),P( 7 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     {
       gp_XYZ aXYZ[4] = {P( 3 ),P( 4 ),P( 2 ),P( 5 )};
-      aQuality = max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[4])),aQuality);
     }
     break;
   }
@@ -751,7 +771,7 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P )
       const int* pInd = SMDS_VolumeTool::GetFaceNodesIndices( type, i, true );
       for ( int p = 0; p < 4; ++p ) // loop on nodes of a quadranle face
         points( p + 1 ) = P( pInd[ p ] + 1 );
-      aQuality = max( aQuality, aspect2D.GetValue( points ));
+      aQuality = std::max( aQuality, aspect2D.GetValue( points ));
     }
   }
   return aQuality;
@@ -780,7 +800,7 @@ double Warping::GetValue( const TSequenceOfXYZ& P )
   if ( P.size() != 4 )
     return 0;
 
-  gp_XYZ G = ( P( 1 ) + P( 2 ) + P( 3 ) + P( 4 ) ) / 4;
+  gp_XYZ G = ( P( 1 ) + P( 2 ) + P( 3 ) + P( 4 ) ) / 4.;
 
   double A1 = ComputeA( P( 1 ), P( 2 ), P( 3 ), G );
   double A2 = ComputeA( P( 2 ), P( 3 ), P( 4 ), G );
@@ -811,7 +831,7 @@ double Warping::ComputeA( const gp_XYZ& thePnt1,
   N.Normalize();
 
   double H = ( thePnt2 - theG ).Dot( N );
-  return asin( fabs( H / L ) ) * 180 / PI;
+  return asin( fabs( H / L ) ) * 180. / PI;
 }
 
 double Warping::GetBadRate( double Value, int /*nbNodes*/ ) const
@@ -835,13 +855,13 @@ SMDSAbs_ElementType Warping::GetType() const
 double Taper::GetValue( const TSequenceOfXYZ& P )
 {
   if ( P.size() != 4 )
-    return 0;
+    return 0.;
 
   // Compute taper
-  double J1 = getArea( P( 4 ), P( 1 ), P( 2 ) ) / 2;
-  double J2 = getArea( P( 3 ), P( 1 ), P( 2 ) ) / 2;
-  double J3 = getArea( P( 2 ), P( 3 ), P( 4 ) ) / 2;
-  double J4 = getArea( P( 3 ), P( 4 ), P( 1 ) ) / 2;
+  double J1 = getArea( P( 4 ), P( 1 ), P( 2 ) ) / 2.;
+  double J2 = getArea( P( 3 ), P( 1 ), P( 2 ) ) / 2.;
+  double J3 = getArea( P( 2 ), P( 3 ), P( 4 ) ) / 2.;
+  double J4 = getArea( P( 3 ), P( 4 ), P( 1 ) ) / 2.;
 
   double JA = 0.25 * ( J1 + J2 + J3 + J4 );
   if ( JA <= Precision::Confusion() )
@@ -875,42 +895,46 @@ SMDSAbs_ElementType Taper::GetType() const
 */
 static inline double skewAngle( const gp_XYZ& p1, const gp_XYZ& p2, const gp_XYZ& p3 )
 {
-  gp_XYZ p12 = ( p2 + p1 ) / 2;
-  gp_XYZ p23 = ( p3 + p2 ) / 2;
-  gp_XYZ p31 = ( p3 + p1 ) / 2;
+  gp_XYZ p12 = ( p2 + p1 ) / 2.;
+  gp_XYZ p23 = ( p3 + p2 ) / 2.;
+  gp_XYZ p31 = ( p3 + p1 ) / 2.;
 
   gp_Vec v1( p31 - p2 ), v2( p12 - p23 );
 
-  return v1.Magnitude() < gp::Resolution() || v2.Magnitude() < gp::Resolution() ? 0 : v1.Angle( v2 );
+  return v1.Magnitude() < gp::Resolution() || v2.Magnitude() < gp::Resolution() ? 0. : v1.Angle( v2 );
 }
 
 double Skew::GetValue( const TSequenceOfXYZ& P )
 {
   if ( P.size() != 3 && P.size() != 4 )
-    return 0;
+    return 0.;
 
   // Compute skew
-  static double PI2 = PI / 2;
+  static double PI2 = PI / 2.;
   if ( P.size() == 3 )
   {
     double A0 = fabs( PI2 - skewAngle( P( 3 ), P( 1 ), P( 2 ) ) );
     double A1 = fabs( PI2 - skewAngle( P( 1 ), P( 2 ), P( 3 ) ) );
     double A2 = fabs( PI2 - skewAngle( P( 2 ), P( 3 ), P( 1 ) ) );
 
-    return Max( A0, Max( A1, A2 ) ) * 180 / PI;
+    return Max( A0, Max( A1, A2 ) ) * 180. / PI;
   }
   else
   {
-    gp_XYZ p12 = ( P( 1 ) + P( 2 ) ) / 2;
-    gp_XYZ p23 = ( P( 2 ) + P( 3 ) ) / 2;
-    gp_XYZ p34 = ( P( 3 ) + P( 4 ) ) / 2;
-    gp_XYZ p41 = ( P( 4 ) + P( 1 ) ) / 2;
+    gp_XYZ p12 = ( P( 1 ) + P( 2 ) ) / 2.;
+    gp_XYZ p23 = ( P( 2 ) + P( 3 ) ) / 2.;
+    gp_XYZ p34 = ( P( 3 ) + P( 4 ) ) / 2.;
+    gp_XYZ p41 = ( P( 4 ) + P( 1 ) ) / 2.;
 
     gp_Vec v1( p34 - p12 ), v2( p23 - p41 );
     double A = v1.Magnitude() <= gp::Resolution() || v2.Magnitude() <= gp::Resolution()
-      ? 0 : fabs( PI2 - v1.Angle( v2 ) );
+      ? 0. : fabs( PI2 - v1.Angle( v2 ) );
 
-    return A * 180 / PI;
+    //BUG SWP12743
+    if ( A < Precision::Angular() )
+      return 0.;
+
+    return A * 180. / PI;
   }
 }
 
@@ -1583,7 +1607,7 @@ bool FreeEdges::IsSatisfy( long theId )
     return false;
 
   int i = 0, nbNodes = aFace->NbNodes();
-  vector <const SMDS_MeshNode*> aNodes( nbNodes+1 );
+  std::vector <const SMDS_MeshNode*> aNodes( nbNodes+1 );
   while( anIter->more() )
   {
     const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next();
@@ -2516,6 +2540,7 @@ ElementsOnSurface::ElementsOnSurface()
   myType = SMDSAbs_All;
   mySurf.Nullify();
   myToler = Precision::Confusion();
+  myUseBoundaries = false;
 }
 
 ElementsOnSurface::~ElementsOnSurface()
@@ -2528,7 +2553,6 @@ void ElementsOnSurface::SetMesh( const SMDS_Mesh* theMesh )
   if ( myMesh == theMesh )
     return;
   myMesh = theMesh;
-  myIds.Clear();
   process();
 }
 
@@ -2541,25 +2565,41 @@ SMDSAbs_ElementType ElementsOnSurface::GetType() const
 { return myType; }
 
 void ElementsOnSurface::SetTolerance( const double theToler )
-{ myToler = theToler; }
+{
+  if ( myToler != theToler )
+    myIds.Clear();
+  myToler = theToler;
+}
 
 double ElementsOnSurface::GetTolerance() const
+{ return myToler; }
+
+void ElementsOnSurface::SetUseBoundaries( bool theUse )
 {
-  return myToler;
+  if ( myUseBoundaries != theUse ) {
+    myUseBoundaries = theUse;
+    SetSurface( mySurf, myType );
+  }
 }
 
 void ElementsOnSurface::SetSurface( const TopoDS_Shape& theShape,
                                     const SMDSAbs_ElementType theType )
 {
+  myIds.Clear();
   myType = theType;
   mySurf.Nullify();
   if ( theShape.IsNull() || theShape.ShapeType() != TopAbs_FACE )
-  {
-    mySurf.Nullify();
     return;
-  }
-  TopoDS_Face aFace = TopoDS::Face( theShape );
-  mySurf = BRep_Tool::Surface( aFace );
+  mySurf = TopoDS::Face( theShape );
+  BRepAdaptor_Surface SA( mySurf, myUseBoundaries );
+  Standard_Real
+    u1 = SA.FirstUParameter(),
+    u2 = SA.LastUParameter(),
+    v1 = SA.FirstVParameter(),
+    v2 = SA.LastVParameter();
+  Handle(Geom_Surface) surf = BRep_Tool::Surface( mySurf );
+  myProjector.Init( surf, u1,u2, v1,v2 );
+  process();
 }
 
 void ElementsOnSurface::process()
@@ -2573,6 +2613,7 @@ void ElementsOnSurface::process()
 
   if ( myType == SMDSAbs_Face || myType == SMDSAbs_All )
   {
+    myIds.ReSize( myMesh->NbFaces() );
     SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
     for(; anIter->more(); )
       process( anIter->next() );
@@ -2580,6 +2621,7 @@ void ElementsOnSurface::process()
 
   if ( myType == SMDSAbs_Edge || myType == SMDSAbs_All )
   {
+    myIds.ReSize( myIds.Extent() + myMesh->NbEdges() );
     SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
     for(; anIter->more(); )
       process( anIter->next() );
@@ -2587,6 +2629,7 @@ void ElementsOnSurface::process()
 
   if ( myType == SMDSAbs_Node )
   {
+    myIds.ReSize( myMesh->NbNodes() );
     SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
     for(; anIter->more(); )
       process( anIter->next() );
@@ -2610,32 +2653,281 @@ void ElementsOnSurface::process( const SMDS_MeshElement* theElemPtr )
     myIds.Add( theElemPtr->GetID() );
 }
 
-bool ElementsOnSurface::isOnSurface( const SMDS_MeshNode* theNode ) const
+bool ElementsOnSurface::isOnSurface( const SMDS_MeshNode* theNode )
 {
   if ( mySurf.IsNull() )
     return false;
 
   gp_Pnt aPnt( theNode->X(), theNode->Y(), theNode->Z() );
-  double aToler2 = myToler * myToler;
-  if ( mySurf->IsKind(STANDARD_TYPE(Geom_Plane)))
+  //  double aToler2 = myToler * myToler;
+//   if ( mySurf->IsKind(STANDARD_TYPE(Geom_Plane)))
+//   {
+//     gp_Pln aPln = Handle(Geom_Plane)::DownCast(mySurf)->Pln();
+//     if ( aPln.SquareDistance( aPnt ) > aToler2 )
+//       return false;
+//   }
+//   else if ( mySurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)))
+//   {
+//     gp_Cylinder aCyl = Handle(Geom_CylindricalSurface)::DownCast(mySurf)->Cylinder();
+//     double aRad = aCyl.Radius();
+//     gp_Ax3 anAxis = aCyl.Position();
+//     gp_XYZ aLoc = aCyl.Location().XYZ();
+//     double aXDist = anAxis.XDirection().XYZ() * ( aPnt.XYZ() - aLoc );
+//     double aYDist = anAxis.YDirection().XYZ() * ( aPnt.XYZ() - aLoc );
+//     if ( fabs(aXDist*aXDist + aYDist*aYDist - aRad*aRad) > aToler2 )
+//       return false;
+//   }
+//   else
+//     return false;
+  myProjector.Perform( aPnt );
+  bool isOn = ( myProjector.IsDone() && myProjector.LowerDistance() <= myToler );
+
+  return isOn;
+}
+
+
+/*
+  ElementsOnShape
+*/
+
+ElementsOnShape::ElementsOnShape()
+  : myMesh(0),
+    myType(SMDSAbs_All),
+    myToler(Precision::Confusion()),
+    myAllNodesFlag(false)
+{
+  myCurShapeType = TopAbs_SHAPE;
+}
+
+ElementsOnShape::~ElementsOnShape()
+{
+}
+
+void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh)
+{
+  if (myMesh != theMesh) {
+    myMesh = theMesh;
+    SetShape(myShape, myType);
+  }
+}
+
+bool ElementsOnShape::IsSatisfy (long theElementId)
+{
+  return myIds.Contains(theElementId);
+}
+
+SMDSAbs_ElementType ElementsOnShape::GetType() const
+{
+  return myType;
+}
+
+void ElementsOnShape::SetTolerance (const double theToler)
+{
+  if (myToler != theToler) {
+    myToler = theToler;
+    SetShape(myShape, myType);
+  }
+}
+
+double ElementsOnShape::GetTolerance() const
+{
+  return myToler;
+}
+
+void ElementsOnShape::SetAllNodes (bool theAllNodes)
+{
+  if (myAllNodesFlag != theAllNodes) {
+    myAllNodesFlag = theAllNodes;
+    SetShape(myShape, myType);
+  }
+}
+
+void ElementsOnShape::SetShape (const TopoDS_Shape&       theShape,
+                                const SMDSAbs_ElementType theType)
+{
+  myType = theType;
+  myShape = theShape;
+  myIds.Clear();
+
+  if (myMesh == 0) return;
+
+  switch (myType)
   {
-    gp_Pln aPln = Handle(Geom_Plane)::DownCast(mySurf)->Pln();
-    if ( aPln.SquareDistance( aPnt ) > aToler2 )
-      return false;
+  case SMDSAbs_All:
+    myIds.ReSize(myMesh->NbEdges() + myMesh->NbFaces() + myMesh->NbVolumes());
+    break;
+  case SMDSAbs_Node:
+    myIds.ReSize(myMesh->NbNodes());
+    break;
+  case SMDSAbs_Edge:
+    myIds.ReSize(myMesh->NbEdges());
+    break;
+  case SMDSAbs_Face:
+    myIds.ReSize(myMesh->NbFaces());
+    break;
+  case SMDSAbs_Volume:
+    myIds.ReSize(myMesh->NbVolumes());
+    break;
+  default:
+    break;
   }
-  else if ( mySurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)))
+
+  myShapesMap.Clear();
+  addShape(myShape);
+}
+
+void ElementsOnShape::addShape (const TopoDS_Shape& theShape)
+{
+  if (theShape.IsNull() || myMesh == 0)
+    return;
+
+  if (!myShapesMap.Add(theShape)) return;
+
+  myCurShapeType = theShape.ShapeType();
+  switch (myCurShapeType)
   {
-    gp_Cylinder aCyl = Handle(Geom_CylindricalSurface)::DownCast(mySurf)->Cylinder();
-    double aRad = aCyl.Radius();
-    gp_Ax3 anAxis = aCyl.Position();
-    gp_XYZ aLoc = aCyl.Location().XYZ();
-    double aXDist = anAxis.XDirection().XYZ() * ( aPnt.XYZ() - aLoc );
-    double aYDist = anAxis.YDirection().XYZ() * ( aPnt.XYZ() - aLoc );
-    if ( fabs(aXDist*aXDist + aYDist*aYDist - aRad*aRad) > aToler2 )
-      return false;
+  case TopAbs_COMPOUND:
+  case TopAbs_COMPSOLID:
+  case TopAbs_SHELL:
+  case TopAbs_WIRE:
+    {
+      TopoDS_Iterator anIt (theShape, Standard_True, Standard_True);
+      for (; anIt.More(); anIt.Next()) addShape(anIt.Value());
+    }
+    break;
+  case TopAbs_SOLID:
+    {
+      myCurSC.Load(theShape);
+      process();
+    }
+    break;
+  case TopAbs_FACE:
+    {
+      TopoDS_Face aFace = TopoDS::Face(theShape);
+      BRepAdaptor_Surface SA (aFace, true);
+      Standard_Real
+        u1 = SA.FirstUParameter(),
+        u2 = SA.LastUParameter(),
+        v1 = SA.FirstVParameter(),
+        v2 = SA.LastVParameter();
+      Handle(Geom_Surface) surf = BRep_Tool::Surface(aFace);
+      myCurProjFace.Init(surf, u1,u2, v1,v2);
+      myCurFace = aFace;
+      process();
+    }
+    break;
+  case TopAbs_EDGE:
+    {
+      TopoDS_Edge anEdge = TopoDS::Edge(theShape);
+      Standard_Real u1, u2;
+      Handle(Geom_Curve) curve = BRep_Tool::Curve(anEdge, u1, u2);
+      myCurProjEdge.Init(curve, u1, u2);
+      process();
+    }
+    break;
+  case TopAbs_VERTEX:
+    {
+      TopoDS_Vertex aV = TopoDS::Vertex(theShape);
+      myCurPnt = BRep_Tool::Pnt(aV);
+      process();
+    }
+    break;
+  default:
+    break;
+  }
+}
+
+void ElementsOnShape::process()
+{
+  if (myShape.IsNull() || myMesh == 0)
+    return;
+
+  if (myType == SMDSAbs_Node)
+  {
+    SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
+    while (anIter->more())
+      process(anIter->next());
   }
   else
-    return false;
+  {
+    if (myType == SMDSAbs_Edge || myType == SMDSAbs_All)
+    {
+      SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
+      while (anIter->more())
+        process(anIter->next());
+    }
 
-  return true;
+    if (myType == SMDSAbs_Face || myType == SMDSAbs_All)
+    {
+      SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
+      while (anIter->more()) {
+        process(anIter->next());
+      }
+    }
+
+    if (myType == SMDSAbs_Volume || myType == SMDSAbs_All)
+    {
+      SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
+      while (anIter->more())
+        process(anIter->next());
+    }
+  }
+}
+
+void ElementsOnShape::process (const SMDS_MeshElement* theElemPtr)
+{
+  if (myShape.IsNull())
+    return;
+
+  SMDS_ElemIteratorPtr aNodeItr = theElemPtr->nodesIterator();
+  bool isSatisfy = myAllNodesFlag;
+
+  while (aNodeItr->more() && (isSatisfy == myAllNodesFlag))
+  {
+    SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
+    gp_Pnt aPnt (aNode->X(), aNode->Y(), aNode->Z());
+
+    switch (myCurShapeType)
+    {
+    case TopAbs_SOLID:
+      {
+        myCurSC.Perform(aPnt, myToler);
+        isSatisfy = (myCurSC.State() == TopAbs_IN || myCurSC.State() == TopAbs_ON);
+      }
+      break;
+    case TopAbs_FACE:
+      {
+        myCurProjFace.Perform(aPnt);
+        isSatisfy = (myCurProjFace.IsDone() && myCurProjFace.LowerDistance() <= myToler);
+        if (isSatisfy)
+        {
+          // check relatively the face
+          Quantity_Parameter u, v;
+          myCurProjFace.LowerDistanceParameters(u, v);
+          gp_Pnt2d aProjPnt (u, v);
+          BRepClass_FaceClassifier aClsf (myCurFace, aProjPnt, myToler);
+          isSatisfy = (aClsf.State() == TopAbs_IN || aClsf.State() == TopAbs_ON);
+        }
+      }
+      break;
+    case TopAbs_EDGE:
+      {
+        myCurProjEdge.Perform(aPnt);
+        isSatisfy = (myCurProjEdge.NbPoints() > 0 && myCurProjEdge.LowerDistance() <= myToler);
+      }
+      break;
+    case TopAbs_VERTEX:
+      {
+        isSatisfy = (aPnt.Distance(myCurPnt) <= myToler);
+      }
+      break;
+    default:
+      {
+        isSatisfy = false;
+      }
+    }
+  }
+
+  if (isSatisfy)
+    myIds.Add(theElemPtr->GetID());
 }