X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FControls%2FSMESH_Controls.cxx;h=d007834226ada28b4db9ce96c1c3cd24b168d0ae;hb=85ce2501861082c42cc409453164d4f600e13107;hp=c00cbae43554bcf0c5ea8f40f2d46537bad8eed7;hpb=4ff5bd61540272713e48de1eee75625028c32155;p=modules%2Fsmesh.git diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index c00cbae43..d00783422 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -1,4 +1,6 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This library is free software; you can redistribute it and/or @@ -15,31 +17,41 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org - +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include "SMESH_ControlsDef.hxx" #include +#include +#include #include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + #include #include #include -#include #include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include "SMDS_Mesh.hxx" #include "SMDS_Iterator.hxx" @@ -49,6 +61,8 @@ #include "SMDS_QuadraticFaceOfNodes.hxx" #include "SMDS_QuadraticEdge.hxx" +#include "SMESHDS_Mesh.hxx" +#include "SMESHDS_GroupBase.hxx" /* AUXILIARY METHODS @@ -128,7 +142,7 @@ namespace{ } } } - int aResult = max ( aResult0, aResult1 ); + int aResult = std::max ( aResult0, aResult1 ); // TColStd_MapOfInteger aMap; @@ -246,6 +260,7 @@ void NumericalFunctor::SetPrecision( const long thePrecision ) double NumericalFunctor::GetValue( long theId ) { + myCurrElement = myMesh->FindElement( theId ); TSequenceOfXYZ P; if ( GetPoints( theId, P )) { @@ -349,36 +364,49 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P ) if ( nbNodes < 3 ) return 0; - // Compute lengths of the sides - - 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 ) ); - // Compute aspect ratio - if ( nbNodes == 3 ) - { + if ( nbNodes == 3 ) { + // Compute lengths of the sides + 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 ) ); // Q = alfa * h * p / S, where // // alfa = sqrt( 3 ) / 6 // h - length of the longest edge // p - half perimeter // S - triangle surface - const double alfa = sqrt( 3. ) / 6.; double maxLen = Max( aLen[ 0 ], Max( aLen[ 1 ], aLen[ 2 ] ) ); double half_perimeter = ( aLen[0] + aLen[1] + aLen[2] ) / 2.; double anArea = getArea( P( 1 ), P( 2 ), P( 3 ) ); if ( anArea <= Precision::Confusion() ) return 0.; - return alfa * maxLen * half_perimeter / anArea; } - else - { + else if ( nbNodes == 6 ) { // quadratic triangles + // Compute lengths of the sides + 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) ); + // Q = alfa * h * p / S, where + // + // alfa = sqrt( 3 ) / 6 + // h - length of the longest edge + // p - half perimeter + // S - triangle surface + const double alfa = sqrt( 3. ) / 6.; + double maxLen = Max( aLen[ 0 ], Max( aLen[ 1 ], aLen[ 2 ] ) ); + double half_perimeter = ( aLen[0] + aLen[1] + aLen[2] ) / 2.; + double anArea = getArea( P(1), P(3), P(5) ); + if ( anArea <= Precision::Confusion() ) + return 0.; + return alfa * maxLen * half_perimeter / anArea; + } + else if( nbNodes == 4 ) { // quadrangle // return aspect ratio of the worst triange which can be built // taking three nodes of the quadrangle TSequenceOfXYZ triaPnts(3); @@ -397,6 +425,27 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P ) triaPnts(1) = P(3); ar = Max ( ar, GetValue( triaPnts )); + return ar; + } + else { // nbNodes==8 - quadratic quadrangle + // return aspect ratio of the worst triange which can be built + // taking three nodes of the quadrangle + TSequenceOfXYZ triaPnts(3); + // triangle on nodes 1 3 2 + triaPnts(1) = P(1); + triaPnts(2) = P(5); + triaPnts(3) = P(3); + double ar = GetValue( triaPnts ); + // triangle on nodes 1 3 4 + triaPnts(3) = P(7); + ar = Max ( ar, GetValue( triaPnts )); + // triangle on nodes 1 2 4 + triaPnts(2) = P(3); + ar = Max ( ar, GetValue( triaPnts )); + // triangle on nodes 3 2 4 + triaPnts(1) = P(5); + ar = Max ( ar, GetValue( triaPnts )); + return ar; } } @@ -471,11 +520,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; } @@ -484,7 +533,18 @@ namespace{ 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] = { @@ -518,187 +578,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; } @@ -715,7 +776,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; @@ -744,7 +805,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 ); @@ -775,7 +836,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 @@ -799,13 +860,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() ) @@ -839,42 +900,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; } } @@ -1292,60 +1357,58 @@ double MultiConnection2D::GetValue( const TSequenceOfXYZ& P ) double MultiConnection2D::GetValue( long theElementId ) { - TSequenceOfXYZ P; int aResult = 0; - if (GetPoints(theElementId,P)){ - const SMDS_MeshElement* anFaceElem = myMesh->FindElement( theElementId ); - SMDSAbs_ElementType aType = anFaceElem->GetType(); - - int len = P.size(); - - TColStd_MapOfInteger aMap; - int aResult = 0; + const SMDS_MeshElement* aFaceElem = myMesh->FindElement(theElementId); + SMDSAbs_ElementType aType = aFaceElem->GetType(); - switch (aType){ - case SMDSAbs_All: - case SMDSAbs_Node: - case SMDSAbs_Edge: - case SMDSAbs_Face: - if (len == 3){ // triangles - int Nb[3] = {0,0,0}; - - int i=0; - SMDS_ElemIteratorPtr anIter = anFaceElem->nodesIterator(); - if ( anIter != 0 ) { - while( anIter->more() ) { - const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); - if ( aNode == 0 ){ - break; - } - SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator(); - while( anElemIter->more() ) { - const SMDS_MeshElement* anElem = anElemIter->next(); - if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) { - int anId = anElem->GetID(); - - if ( anIter->more() ) // i.e. first node - aMap.Add( anId ); - else if ( aMap.Contains( anId ) ){ - Nb[i]++; - } - } - else if ( anElem != 0 && anElem->GetType() == SMDSAbs_Edge ) i++; - } - } - } - - aResult = Max(Max(Nb[0],Nb[1]),Nb[2]); + switch (aType) { + case SMDSAbs_Face: + { + int i = 0, len = aFaceElem->NbNodes(); + SMDS_ElemIteratorPtr anIter = aFaceElem->nodesIterator(); + if (!anIter) break; + + const SMDS_MeshNode *aNode, *aNode0; + TColStd_MapOfInteger aMap, aMapPrev; + + for (i = 0; i <= len; i++) { + aMapPrev = aMap; + aMap.Clear(); + + int aNb = 0; + if (anIter->more()) { + aNode = (SMDS_MeshNode*)anIter->next(); + } else { + if (i == len) + aNode = aNode0; + else + break; + } + if (!aNode) break; + if (i == 0) aNode0 = aNode; + + SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator(); + while (anElemIter->more()) { + const SMDS_MeshElement* anElem = anElemIter->next(); + if (anElem != 0 && anElem->GetType() == SMDSAbs_Face) { + int anId = anElem->GetID(); + + aMap.Add(anId); + if (aMapPrev.Contains(anId)) { + aNb++; + } + } + } + aResult = Max(aResult, aNb); } - break; - case SMDSAbs_Volume: - default: aResult=0; } - + break; + default: + aResult = 0; } - return aResult;//getNbMultiConnection( myMesh, theId ); + + return aResult; } double MultiConnection2D::GetBadRate( double Value, int /*nbNodes*/ ) const @@ -1545,11 +1608,11 @@ bool FreeEdges::IsSatisfy( long theId ) else { anIter = aFace->nodesIterator(); } - if ( anIter != 0 ) + if ( anIter == 0 ) return false; int i = 0, nbNodes = aFace->NbNodes(); - vector aNodes( nbNodes+1 ); + std::vector aNodes( nbNodes+1 ); while( anIter->more() ) { const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); @@ -1633,6 +1696,309 @@ void FreeEdges::GetBoreders(TBorders& theBorders) //std::cout<<"theBorders.size() = "<FindNode( theNodeId ); + if (!aNode) + return false; + + return (aNode->NbInverseElements() < 1); +} + +SMDSAbs_ElementType FreeNodes::GetType() const +{ + return SMDSAbs_Node; +} + + +/* + Class : FreeFaces + Description : Predicate for free faces +*/ + +FreeFaces::FreeFaces() +{ + myMesh = 0; +} + +void FreeFaces::SetMesh( const SMDS_Mesh* theMesh ) +{ + myMesh = theMesh; +} + +bool FreeFaces::IsSatisfy( long theId ) +{ + if (!myMesh) return false; + // check that faces nodes refers to less than two common volumes + const SMDS_MeshElement* aFace = myMesh->FindElement( theId ); + if ( !aFace || aFace->GetType() != SMDSAbs_Face ) + return false; + + int nbNode = aFace->NbNodes(); + + // collect volumes check that number of volumss with count equal nbNode not less than 2 + typedef map< SMDS_MeshElement*, int > TMapOfVolume; // map of volume counters + typedef map< SMDS_MeshElement*, int >::iterator TItrMapOfVolume; // iterator + TMapOfVolume mapOfVol; + + SMDS_ElemIteratorPtr nodeItr = aFace->nodesIterator(); + while ( nodeItr->more() ) { + const SMDS_MeshNode* aNode = static_cast(nodeItr->next()); + if ( !aNode ) continue; + SMDS_ElemIteratorPtr volItr = aNode->GetInverseElementIterator(SMDSAbs_Volume); + while ( volItr->more() ) { + SMDS_MeshElement* aVol = (SMDS_MeshElement*)volItr->next(); + TItrMapOfVolume itr = mapOfVol.insert(make_pair(aVol, 0)).first; + (*itr).second++; + } + } + int nbVol = 0; + TItrMapOfVolume volItr = mapOfVol.begin(); + TItrMapOfVolume volEnd = mapOfVol.end(); + for ( ; volItr != volEnd; ++volItr ) + if ( (*volItr).second >= nbNode ) + nbVol++; + // face is not free if number of volumes constructed on thier nodes more than one + return (nbVol < 2); +} + +SMDSAbs_ElementType FreeFaces::GetType() const +{ + return SMDSAbs_Face; +} + +/* + Class : LinearOrQuadratic + Description : Predicate to verify whether a mesh element is linear +*/ + +LinearOrQuadratic::LinearOrQuadratic() +{ + myMesh = 0; +} + +void LinearOrQuadratic::SetMesh( const SMDS_Mesh* theMesh ) +{ + myMesh = theMesh; +} + +bool LinearOrQuadratic::IsSatisfy( long theId ) +{ + if (!myMesh) return false; + const SMDS_MeshElement* anElem = myMesh->FindElement( theId ); + if ( !anElem || (myType != SMDSAbs_All && anElem->GetType() != myType) ) + return false; + return (!anElem->IsQuadratic()); +} + +void LinearOrQuadratic::SetType( SMDSAbs_ElementType theType ) +{ + myType = theType; +} + +SMDSAbs_ElementType LinearOrQuadratic::GetType() const +{ + return myType; +} + +/* + Class : GroupColor + Description : Functor for check color of group to whic mesh element belongs to +*/ + +GroupColor::GroupColor() +{ +} + +bool GroupColor::IsSatisfy( long theId ) +{ + return (myIDs.find( theId ) != myIDs.end()); +} + +void GroupColor::SetType( SMDSAbs_ElementType theType ) +{ + myType = theType; +} + +SMDSAbs_ElementType GroupColor::GetType() const +{ + return myType; +} + +static bool isEqual( const Quantity_Color& theColor1, + const Quantity_Color& theColor2 ) +{ + // tolerance to compare colors + const double tol = 5*1e-3; + return ( fabs( theColor1.Red() - theColor2.Red() ) < tol && + fabs( theColor1.Green() - theColor2.Green() ) < tol && + fabs( theColor1.Blue() - theColor2.Blue() ) < tol ); +} + + +void GroupColor::SetMesh( const SMDS_Mesh* theMesh ) +{ + myIDs.clear(); + + const SMESHDS_Mesh* aMesh = dynamic_cast(theMesh); + if ( !aMesh ) + return; + + int nbGrp = aMesh->GetNbGroups(); + if ( !nbGrp ) + return; + + // iterates on groups and find necessary elements ids + const std::set& aGroups = aMesh->GetGroups(); + set::const_iterator GrIt = aGroups.begin(); + for (; GrIt != aGroups.end(); GrIt++) { + SMESHDS_GroupBase* aGrp = (*GrIt); + if ( !aGrp ) + continue; + // check type and color of group + if ( !isEqual( myColor, aGrp->GetColor() ) ) + continue; + if ( myType != SMDSAbs_All && myType != (SMDSAbs_ElementType)aGrp->GetType() ) + continue; + + SMDSAbs_ElementType aGrpElType = (SMDSAbs_ElementType)aGrp->GetType(); + if ( myType == aGrpElType || (myType == SMDSAbs_All && aGrpElType != SMDSAbs_Node) ) { + // add elements IDS into control + int aSize = aGrp->Extent(); + for (int i = 0; i < aSize; i++) + myIDs.insert( aGrp->GetID(i+1) ); + } + } +} + +void GroupColor::SetColorStr( const TCollection_AsciiString& theStr ) +{ + TCollection_AsciiString aStr = theStr; + aStr.RemoveAll( ' ' ); + aStr.RemoveAll( '\t' ); + for ( int aPos = aStr.Search( ";;" ); aPos != -1; aPos = aStr.Search( ";;" ) ) + aStr.Remove( aPos, 2 ); + Standard_Real clr[3]; + clr[0] = clr[1] = clr[2] = 0.; + for ( int i = 0; i < 3; i++ ) { + TCollection_AsciiString tmpStr = aStr.Token( ";", i+1 ); + if ( !tmpStr.IsEmpty() && tmpStr.IsRealValue() ) + clr[i] = tmpStr.RealValue(); + } + myColor = Quantity_Color( clr[0], clr[1], clr[2], Quantity_TOC_RGB ); +} + +//======================================================================= +// name : GetRangeStr +// Purpose : Get range as a string. +// Example: "1,2,3,50-60,63,67,70-" +//======================================================================= +void GroupColor::GetColorStr( TCollection_AsciiString& theResStr ) const +{ + theResStr.Clear(); + theResStr += TCollection_AsciiString( myColor.Red() ); + theResStr += TCollection_AsciiString( ";" ) + TCollection_AsciiString( myColor.Green() ); + theResStr += TCollection_AsciiString( ";" ) + TCollection_AsciiString( myColor.Blue() ); +} + +/* + Class : ElemGeomType + Description : Predicate to check element geometry type +*/ + +ElemGeomType::ElemGeomType() +{ + myMesh = 0; + myType = SMDSAbs_All; + myGeomType = SMDSGeom_TRIANGLE; +} + +void ElemGeomType::SetMesh( const SMDS_Mesh* theMesh ) +{ + myMesh = theMesh; +} + +bool ElemGeomType::IsSatisfy( long theId ) +{ + if (!myMesh) return false; + const SMDS_MeshElement* anElem = myMesh->FindElement( theId ); + const SMDSAbs_ElementType anElemType = anElem->GetType(); + if ( !anElem || (myType != SMDSAbs_All && anElemType != myType) ) + return false; + const int aNbNode = anElem->NbNodes(); + bool isOk = false; + switch( anElemType ) + { + case SMDSAbs_Node: + isOk = (myGeomType == SMDSGeom_POINT); + break; + + case SMDSAbs_Edge: + isOk = (myGeomType == SMDSGeom_EDGE); + break; + + case SMDSAbs_Face: + if ( myGeomType == SMDSGeom_TRIANGLE ) + isOk = (!anElem->IsPoly() && aNbNode == 3); + else if ( myGeomType == SMDSGeom_QUADRANGLE ) + isOk = (!anElem->IsPoly() && aNbNode == 4); + else if ( myGeomType == SMDSGeom_POLYGON ) + isOk = anElem->IsPoly(); + break; + + case SMDSAbs_Volume: + if ( myGeomType == SMDSGeom_TETRA ) + isOk = (!anElem->IsPoly() && aNbNode == 4); + else if ( myGeomType == SMDSGeom_PYRAMID ) + isOk = (!anElem->IsPoly() && aNbNode == 5); + else if ( myGeomType == SMDSGeom_PENTA ) + isOk = (!anElem->IsPoly() && aNbNode == 6); + else if ( myGeomType == SMDSGeom_HEXA ) + isOk = (!anElem->IsPoly() && aNbNode == 8); + else if ( myGeomType == SMDSGeom_POLYHEDRA ) + isOk = anElem->IsPoly(); + break; + default: break; + } + return isOk; +} + +void ElemGeomType::SetType( SMDSAbs_ElementType theType ) +{ + myType = theType; +} + +SMDSAbs_ElementType ElemGeomType::GetType() const +{ + return myType; +} + +void ElemGeomType::SetGeomType( SMDSAbs_GeometryType theType ) +{ + myGeomType = theType; +} + +SMDSAbs_GeometryType ElemGeomType::GetGeomType() const +{ + return myGeomType; +} + /* Class : RangeOfIds Description : Predicate for Range of Ids. @@ -2482,6 +2848,7 @@ ElementsOnSurface::ElementsOnSurface() myType = SMDSAbs_All; mySurf.Nullify(); myToler = Precision::Confusion(); + myUseBoundaries = false; } ElementsOnSurface::~ElementsOnSurface() @@ -2494,7 +2861,6 @@ void ElementsOnSurface::SetMesh( const SMDS_Mesh* theMesh ) if ( myMesh == theMesh ) return; myMesh = theMesh; - myIds.Clear(); process(); } @@ -2507,25 +2873,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() @@ -2539,6 +2921,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() ); @@ -2546,6 +2929,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() ); @@ -2553,6 +2937,7 @@ void ElementsOnSurface::process() if ( myType == SMDSAbs_Node ) { + myIds.ReSize( myMesh->NbNodes() ); SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator(); for(; anIter->more(); ) process( anIter->next() ); @@ -2576,32 +2961,292 @@ 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; + + gp_XYZ centerXYZ (0, 0, 0); + + while (aNodeItr->more() && (isSatisfy == myAllNodesFlag)) + { + SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next(); + gp_Pnt aPnt (aNode->X(), aNode->Y(), aNode->Z()); + centerXYZ += aPnt.XYZ(); + + 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 && myCurShapeType == TopAbs_SOLID) { // Check the center point for volumes MantisBug 0020168 + centerXYZ /= theElemPtr->NbNodes(); + gp_Pnt aCenterPnt (centerXYZ); + myCurSC.Perform(aCenterPnt, myToler); + if ( !(myCurSC.State() == TopAbs_IN || myCurSC.State() == TopAbs_ON)) + isSatisfy = false; + } + + if (isSatisfy) + myIds.Add(theElemPtr->GetID()); }