X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FControls%2FSMESH_Controls.cxx;h=b1279a6594d78ec63fecc1d34b2f792ea758e6c3;hp=3e1d2f960608365755b8db2d92cb169a75019490;hb=04f997252152407f9180e03f0af428ab2ca6f4be;hpb=cdc7526bd1dadf3ef27bd87406d99729bf5dfb44 diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index 3e1d2f960..b1279a659 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -23,6 +23,7 @@ #include "SMESH_ControlsDef.hxx" #include "SMDS_BallElement.hxx" +#include "SMDS_FacePosition.hxx" #include "SMDS_Iterator.hxx" #include "SMDS_Mesh.hxx" #include "SMDS_MeshElement.hxx" @@ -41,13 +42,16 @@ #include #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -95,6 +99,15 @@ namespace { v2.Magnitude() < gp::Resolution() ? 0 : v1.Angle( v2 ); } + inline double getCos2( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) + { + gp_Vec v1( P1 - P2 ), v2( P3 - P2 ); + double dot = v1 * v2, len1 = v1.SquareMagnitude(), len2 = v2.SquareMagnitude(); + + return ( dot < 0 || len1 < gp::Resolution() || len2 < gp::Resolution() ? -1 : + dot * dot / len1 / len2 ); + } + inline double getArea( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) { gp_Vec aVec1( P2 - P1 ); @@ -134,7 +147,7 @@ namespace { // +-----+------+ +-----+------+ // | | | | // | | | | - // result sould be 2 in both cases + // result should be 2 in both cases // int aResult0 = 0, aResult1 = 0; // last node, it is a medium one in a quadratic edge @@ -261,13 +274,10 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem, } if ( anIter ) { - double xyz[3]; + SMESH_NodeXYZ p; while( anIter->more() ) { - if ( const SMDS_MeshNode* aNode = static_cast( anIter->next() )) - { - aNode->GetXYZ( xyz ); - theRes.push_back( gp_XYZ( xyz[0], xyz[1], xyz[2] )); - } + if ( p.Set( anIter->next() )) + theRes.push_back( p ); } } @@ -616,7 +626,8 @@ double MaxElementLength3D::GetValue( long theElementId ) aVal = Max(aVal,Max(L7,L8)); break; } - case SMDSEntity_Quad_Penta: { // quadratic pentas + case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: { // quadratic pentas double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 )); double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 )); double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 )); @@ -712,21 +723,25 @@ SMDSAbs_ElementType MaxElementLength3D::GetType() const double MinimumAngle::GetValue( const TSequenceOfXYZ& P ) { - double aMin; - - if (P.size() <3) + if ( P.size() < 3 ) return 0.; - aMin = getAngle(P( P.size() ), P( 1 ), P( 2 )); - aMin = Min(aMin,getAngle(P( P.size()-1 ), P( P.size() ), P( 1 ))); + double aMaxCos2; + + aMaxCos2 = getCos2( P( P.size() ), P( 1 ), P( 2 )); + aMaxCos2 = Max( aMaxCos2, getCos2( P( P.size()-1 ), P( P.size() ), P( 1 ))); for ( size_t i = 2; i < P.size(); i++ ) { - double A0 = getAngle( P( i-1 ), P( i ), P( i+1 ) ); - aMin = Min(aMin,A0); + double A0 = getCos2( P( i-1 ), P( i ), P( i+1 ) ); + aMaxCos2 = Max( aMaxCos2, A0 ); } + if ( aMaxCos2 < 0 ) + return 0; // all nodes coincide - return aMin * 180.0 / M_PI; + double cos = sqrt( aMaxCos2 ); + if ( cos >= 1 ) return 0; + return acos( cos ) * 180.0 / M_PI; } double MinimumAngle::GetBadRate( double Value, int nbNodes ) const @@ -785,58 +800,51 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P ) 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 ) ); + double aLen1 = getDistance( P( 1 ), P( 2 )); + double aLen2 = getDistance( P( 2 ), P( 3 )); + double aLen3 = getDistance( P( 3 ), 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( 2 ), P( 3 ) ); + const double alfa = sqrt( 3. ) / 6.; + double maxLen = Max( aLen1, Max( aLen2, aLen3 )); + double half_perimeter = ( aLen1 + aLen2 + aLen3 ) / 2.; + double anArea = getArea( P( 1 ), P( 2 ), P( 3 )); if ( anArea <= theEps ) return theInf; return alfa * maxLen * half_perimeter / anArea; } 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) ); + double aLen1 = getDistance( P( 1 ), P( 3 )); + double aLen2 = getDistance( P( 3 ), P( 5 )); + double aLen3 = getDistance( P( 5 ), P( 1 )); + // algo same as for the linear triangle + const double alfa = sqrt( 3. ) / 6.; + double maxLen = Max( aLen1, Max( aLen2, aLen3 )); + double half_perimeter = ( aLen1 + aLen2 + aLen3 ) / 2.; + double anArea = getArea( P( 1 ), P( 3 ), P( 5 )); if ( anArea <= theEps ) return theInf; return alfa * maxLen * half_perimeter / anArea; } else if( nbNodes == 4 ) { // quadrangle // Compute lengths of the sides - std::vector< double > aLen (4); + double aLen[4]; aLen[0] = getDistance( P(1), P(2) ); aLen[1] = getDistance( P(2), P(3) ); aLen[2] = getDistance( P(3), P(4) ); aLen[3] = getDistance( P(4), P(1) ); // Compute lengths of the diagonals - std::vector< double > aDia (2); + double aDia[2]; aDia[0] = getDistance( P(1), P(3) ); aDia[1] = getDistance( P(2), P(4) ); // Compute areas of all triangles which can be built // taking three nodes of the quadrangle - std::vector< double > anArea (4); + double anArea[4]; anArea[0] = getArea( P(1), P(2), P(3) ); anArea[1] = getArea( P(1), P(2), P(4) ); anArea[2] = getArea( P(1), P(3), P(4) ); @@ -852,35 +860,35 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P ) // Si - areas of the triangles const double alpha = sqrt( 1 / 32. ); double L = Max( aLen[ 0 ], - Max( aLen[ 1 ], - Max( aLen[ 2 ], - Max( aLen[ 3 ], - Max( aDia[ 0 ], aDia[ 1 ] ) ) ) ) ); + Max( aLen[ 1 ], + Max( aLen[ 2 ], + Max( aLen[ 3 ], + Max( aDia[ 0 ], aDia[ 1 ] ) ) ) ) ); double C1 = sqrt( ( aLen[0] * aLen[0] + aLen[1] * aLen[1] + aLen[2] * aLen[2] + aLen[3] * aLen[3] ) / 4. ); double C2 = Min( anArea[ 0 ], - Min( anArea[ 1 ], - Min( anArea[ 2 ], anArea[ 3 ] ) ) ); + Min( anArea[ 1 ], + Min( anArea[ 2 ], anArea[ 3 ] ) ) ); if ( C2 <= theEps ) return theInf; return alpha * L * C1 / C2; } else if( nbNodes == 8 || nbNodes == 9 ) { // nbNodes==8 - quadratic quadrangle // Compute lengths of the sides - std::vector< double > aLen (4); + double aLen[4]; aLen[0] = getDistance( P(1), P(3) ); aLen[1] = getDistance( P(3), P(5) ); aLen[2] = getDistance( P(5), P(7) ); aLen[3] = getDistance( P(7), P(1) ); // Compute lengths of the diagonals - std::vector< double > aDia (2); + double aDia[2]; aDia[0] = getDistance( P(1), P(5) ); aDia[1] = getDistance( P(3), P(7) ); // Compute areas of all triangles which can be built // taking three nodes of the quadrangle - std::vector< double > anArea (4); + double anArea[4]; anArea[0] = getArea( P(1), P(3), P(5) ); anArea[1] = getArea( P(1), P(3), P(7) ); anArea[2] = getArea( P(1), P(5), P(7) ); @@ -1271,7 +1279,7 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P ) } // switch(nbNodes) if ( nbNodes > 4 ) { - // avaluate aspect ratio of quadranle faces + // evaluate aspect ratio of quadrangle faces AspectRatio aspect2D; SMDS_VolumeTool::VolumeType type = SMDS_VolumeTool::GetType( nbNodes ); int nbFaces = SMDS_VolumeTool::NbFaces( type ); @@ -1280,7 +1288,7 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P ) if ( SMDS_VolumeTool::NbFaceNodes( type, i ) != 4 ) continue; const int* pInd = SMDS_VolumeTool::GetFaceNodesIndices( type, i, true ); - for ( int p = 0; p < 4; ++p ) // loop on nodes of a quadranle face + for ( int p = 0; p < 4; ++p ) // loop on nodes of a quadrangle face points( p + 1 ) = P( pInd[ p ] + 1 ); aQuality = std::max( aQuality, aspect2D.GetValue( points )); } @@ -1552,246 +1560,240 @@ SMDSAbs_ElementType Length::GetType() const */ //================================================================================ -double Length2D::GetValue( long theElementId ) +double Length2D::GetValue( const TSequenceOfXYZ& P ) { - TSequenceOfXYZ P; - - if ( GetPoints( theElementId, P )) - { - double aVal = 0; - int len = P.size(); - SMDSAbs_EntityType aType = P.getElementEntity(); + double aVal = 0; + int len = P.size(); + SMDSAbs_EntityType aType = P.getElementEntity(); - switch (aType) { - case SMDSEntity_Edge: - if (len == 2) - aVal = getDistance( P( 1 ), P( 2 ) ); - break; - case SMDSEntity_Quad_Edge: - if (len == 3) // quadratic edge - aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 )); - break; - case SMDSEntity_Triangle: - if (len == 3){ // triangles - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 1 )); - aVal = Min(L1,Min(L2,L3)); - } - break; - case SMDSEntity_Quadrangle: - if (len == 4){ // quadrangles - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 4 )); - double L4 = getDistance(P( 4 ),P( 1 )); - aVal = Min(Min(L1,L2),Min(L3,L4)); - } - break; - case SMDSEntity_Quad_Triangle: - case SMDSEntity_BiQuad_Triangle: - if (len >= 6){ // quadratic triangles - double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); - double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); - double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 )); - aVal = Min(L1,Min(L2,L3)); - } - break; - case SMDSEntity_Quad_Quadrangle: - case SMDSEntity_BiQuad_Quadrangle: - if (len >= 8){ // quadratic quadrangles - double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); - double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); - double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 )); - double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 )); - aVal = Min(Min(L1,L2),Min(L3,L4)); - } - break; - case SMDSEntity_Tetra: - if (len == 4){ // tetrahedra - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 1 )); - double L4 = getDistance(P( 1 ),P( 4 )); - double L5 = getDistance(P( 2 ),P( 4 )); - double L6 = getDistance(P( 3 ),P( 4 )); - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - } - break; - case SMDSEntity_Pyramid: - if (len == 5){ // piramids - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 4 )); - double L4 = getDistance(P( 4 ),P( 1 )); - double L5 = getDistance(P( 1 ),P( 5 )); - double L6 = getDistance(P( 2 ),P( 5 )); - double L7 = getDistance(P( 3 ),P( 5 )); - double L8 = getDistance(P( 4 ),P( 5 )); - - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - aVal = Min(aVal,Min(L7,L8)); - } - break; - case SMDSEntity_Penta: - if (len == 6) { // pentaidres - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 1 )); - double L4 = getDistance(P( 4 ),P( 5 )); - double L5 = getDistance(P( 5 ),P( 6 )); - double L6 = getDistance(P( 6 ),P( 4 )); - double L7 = getDistance(P( 1 ),P( 4 )); - double L8 = getDistance(P( 2 ),P( 5 )); - double L9 = getDistance(P( 3 ),P( 6 )); - - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - aVal = Min(aVal,Min(Min(L7,L8),L9)); - } - break; - case SMDSEntity_Hexa: - if (len == 8){ // hexahedron - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 4 )); - double L4 = getDistance(P( 4 ),P( 1 )); - double L5 = getDistance(P( 5 ),P( 6 )); - double L6 = getDistance(P( 6 ),P( 7 )); - double L7 = getDistance(P( 7 ),P( 8 )); - double L8 = getDistance(P( 8 ),P( 5 )); - double L9 = getDistance(P( 1 ),P( 5 )); - double L10= getDistance(P( 2 ),P( 6 )); - double L11= getDistance(P( 3 ),P( 7 )); - double L12= getDistance(P( 4 ),P( 8 )); - - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10))); - aVal = Min(aVal,Min(L11,L12)); - } - break; - case SMDSEntity_Quad_Tetra: - if (len == 10){ // quadratic tetraidrs - double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 6 )) + getDistance(P( 6 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 7 )) + getDistance(P( 7 ),P( 1 )); - double L4 = getDistance(P( 1 ),P( 8 )) + getDistance(P( 8 ),P( 4 )); - double L5 = getDistance(P( 2 ),P( 9 )) + getDistance(P( 9 ),P( 4 )); - double L6 = getDistance(P( 3 ),P( 10 )) + getDistance(P( 10 ),P( 4 )); - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - } - break; - case SMDSEntity_Quad_Pyramid: - if (len == 13){ // quadratic piramids - double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 4 )); - double L4 = getDistance(P( 4 ),P( 9 )) + getDistance(P( 9 ),P( 1 )); - double L5 = getDistance(P( 1 ),P( 10 )) + getDistance(P( 10 ),P( 5 )); - double L6 = getDistance(P( 2 ),P( 11 )) + getDistance(P( 11 ),P( 5 )); - double L7 = getDistance(P( 3 ),P( 12 )) + getDistance(P( 12 ),P( 5 )); - double L8 = getDistance(P( 4 ),P( 13 )) + getDistance(P( 13 ),P( 5 )); - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - aVal = Min(aVal,Min(L7,L8)); - } - break; - case SMDSEntity_Quad_Penta: - if (len == 15){ // quadratic pentaidres - double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 )); - double L4 = getDistance(P( 4 ),P( 10 )) + getDistance(P( 10 ),P( 5 )); - double L5 = getDistance(P( 5 ),P( 11 )) + getDistance(P( 11 ),P( 6 )); - double L6 = getDistance(P( 6 ),P( 12 )) + getDistance(P( 12 ),P( 4 )); - double L7 = getDistance(P( 1 ),P( 13 )) + getDistance(P( 13 ),P( 4 )); - double L8 = getDistance(P( 2 ),P( 14 )) + getDistance(P( 14 ),P( 5 )); - double L9 = getDistance(P( 3 ),P( 15 )) + getDistance(P( 15 ),P( 6 )); - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - aVal = Min(aVal,Min(Min(L7,L8),L9)); - } - break; - case SMDSEntity_Quad_Hexa: - case SMDSEntity_TriQuad_Hexa: - if (len >= 20) { // quadratic hexaider - double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 )); - double L4 = getDistance(P( 4 ),P( 12 )) + getDistance(P( 12 ),P( 1 )); - double L5 = getDistance(P( 5 ),P( 13 )) + getDistance(P( 13 ),P( 6 )); - double L6 = getDistance(P( 6 ),P( 14 )) + getDistance(P( 14 ),P( 7 )); - double L7 = getDistance(P( 7 ),P( 15 )) + getDistance(P( 15 ),P( 8 )); - double L8 = getDistance(P( 8 ),P( 16 )) + getDistance(P( 16 ),P( 5 )); - double L9 = getDistance(P( 1 ),P( 17 )) + getDistance(P( 17 ),P( 5 )); - double L10= getDistance(P( 2 ),P( 18 )) + getDistance(P( 18 ),P( 6 )); - double L11= getDistance(P( 3 ),P( 19 )) + getDistance(P( 19 ),P( 7 )); - double L12= getDistance(P( 4 ),P( 20 )) + getDistance(P( 20 ),P( 8 )); - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10))); - aVal = Min(aVal,Min(L11,L12)); - } - break; - case SMDSEntity_Polygon: - if ( len > 1 ) { - aVal = getDistance( P(1), P( P.size() )); - for ( size_t i = 1; i < P.size(); ++i ) - aVal = Min( aVal, getDistance( P( i ), P( i+1 ))); - } - break; - case SMDSEntity_Quad_Polygon: - if ( len > 2 ) { - aVal = getDistance( P(1), P( P.size() )) + getDistance( P(P.size()), P( P.size()-1 )); - for ( size_t i = 1; i < P.size()-1; i += 2 ) - aVal = Min( aVal, getDistance( P( i ), P( i+1 )) + getDistance( P( i+1 ), P( i+2 ))); - } - break; - case SMDSEntity_Hexagonal_Prism: - if (len == 12) { // hexagonal prism - double L1 = getDistance(P( 1 ),P( 2 )); - double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 4 )); - double L4 = getDistance(P( 4 ),P( 5 )); - double L5 = getDistance(P( 5 ),P( 6 )); - double L6 = getDistance(P( 6 ),P( 1 )); - - double L7 = getDistance(P( 7 ), P( 8 )); - double L8 = getDistance(P( 8 ), P( 9 )); - double L9 = getDistance(P( 9 ), P( 10 )); - double L10= getDistance(P( 10 ),P( 11 )); - double L11= getDistance(P( 11 ),P( 12 )); - double L12= getDistance(P( 12 ),P( 7 )); - - double L13 = getDistance(P( 1 ),P( 7 )); - double L14 = getDistance(P( 2 ),P( 8 )); - double L15 = getDistance(P( 3 ),P( 9 )); - double L16 = getDistance(P( 4 ),P( 10 )); - double L17 = getDistance(P( 5 ),P( 11 )); - double L18 = getDistance(P( 6 ),P( 12 )); - aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); - aVal = Min(aVal, Min(Min(Min(L7,L8),Min(L9,L10)),Min(L11,L12))); - aVal = Min(aVal, Min(Min(Min(L13,L14),Min(L15,L16)),Min(L17,L18))); - } - break; - case SMDSEntity_Polyhedra: - { + switch (aType) { + case SMDSEntity_Edge: + if (len == 2) + aVal = getDistance( P( 1 ), P( 2 ) ); + break; + case SMDSEntity_Quad_Edge: + if (len == 3) // quadratic edge + aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 )); + break; + case SMDSEntity_Triangle: + if (len == 3){ // triangles + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 1 )); + aVal = Min(L1,Min(L2,L3)); } break; - default: - return 0; + case SMDSEntity_Quadrangle: + if (len == 4){ // quadrangles + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 1 )); + aVal = Min(Min(L1,L2),Min(L3,L4)); } + break; + case SMDSEntity_Quad_Triangle: + case SMDSEntity_BiQuad_Triangle: + if (len >= 6){ // quadratic triangles + double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); + double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); + double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 )); + aVal = Min(L1,Min(L2,L3)); + } + break; + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_BiQuad_Quadrangle: + if (len >= 8){ // quadratic quadrangles + double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); + double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); + double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 )); + double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 )); + aVal = Min(Min(L1,L2),Min(L3,L4)); + } + break; + case SMDSEntity_Tetra: + if (len == 4){ // tetrahedra + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 1 )); + double L4 = getDistance(P( 1 ),P( 4 )); + double L5 = getDistance(P( 2 ),P( 4 )); + double L6 = getDistance(P( 3 ),P( 4 )); + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + } + break; + case SMDSEntity_Pyramid: + if (len == 5){ // pyramid + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 1 )); + double L5 = getDistance(P( 1 ),P( 5 )); + double L6 = getDistance(P( 2 ),P( 5 )); + double L7 = getDistance(P( 3 ),P( 5 )); + double L8 = getDistance(P( 4 ),P( 5 )); - if (aVal < 0 ) { - return 0.; + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + aVal = Min(aVal,Min(L7,L8)); } + break; + case SMDSEntity_Penta: + if (len == 6) { // pentahedron + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 1 )); + double L4 = getDistance(P( 4 ),P( 5 )); + double L5 = getDistance(P( 5 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 4 )); + double L7 = getDistance(P( 1 ),P( 4 )); + double L8 = getDistance(P( 2 ),P( 5 )); + double L9 = getDistance(P( 3 ),P( 6 )); - if ( myPrecision >= 0 ) - { - double prec = pow( 10., (double)( myPrecision ) ); - aVal = floor( aVal * prec + 0.5 ) / prec; + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + aVal = Min(aVal,Min(Min(L7,L8),L9)); } + break; + case SMDSEntity_Hexa: + if (len == 8){ // hexahedron + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 1 )); + double L5 = getDistance(P( 5 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 7 )); + double L7 = getDistance(P( 7 ),P( 8 )); + double L8 = getDistance(P( 8 ),P( 5 )); + double L9 = getDistance(P( 1 ),P( 5 )); + double L10= getDistance(P( 2 ),P( 6 )); + double L11= getDistance(P( 3 ),P( 7 )); + double L12= getDistance(P( 4 ),P( 8 )); - return aVal; + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10))); + aVal = Min(aVal,Min(L11,L12)); + } + break; + case SMDSEntity_Quad_Tetra: + if (len == 10){ // quadratic tetrahedron + double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 6 )) + getDistance(P( 6 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 7 )) + getDistance(P( 7 ),P( 1 )); + double L4 = getDistance(P( 1 ),P( 8 )) + getDistance(P( 8 ),P( 4 )); + double L5 = getDistance(P( 2 ),P( 9 )) + getDistance(P( 9 ),P( 4 )); + double L6 = getDistance(P( 3 ),P( 10 )) + getDistance(P( 10 ),P( 4 )); + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + } + break; + case SMDSEntity_Quad_Pyramid: + if (len == 13){ // quadratic pyramid + double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 9 )) + getDistance(P( 9 ),P( 1 )); + double L5 = getDistance(P( 1 ),P( 10 )) + getDistance(P( 10 ),P( 5 )); + double L6 = getDistance(P( 2 ),P( 11 )) + getDistance(P( 11 ),P( 5 )); + double L7 = getDistance(P( 3 ),P( 12 )) + getDistance(P( 12 ),P( 5 )); + double L8 = getDistance(P( 4 ),P( 13 )) + getDistance(P( 13 ),P( 5 )); + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + aVal = Min(aVal,Min(L7,L8)); + } + break; + case SMDSEntity_Quad_Penta: + case SMDSEntity_BiQuad_Penta: + if (len >= 15){ // quadratic pentahedron + double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 )); + double L4 = getDistance(P( 4 ),P( 10 )) + getDistance(P( 10 ),P( 5 )); + double L5 = getDistance(P( 5 ),P( 11 )) + getDistance(P( 11 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 12 )) + getDistance(P( 12 ),P( 4 )); + double L7 = getDistance(P( 1 ),P( 13 )) + getDistance(P( 13 ),P( 4 )); + double L8 = getDistance(P( 2 ),P( 14 )) + getDistance(P( 14 ),P( 5 )); + double L9 = getDistance(P( 3 ),P( 15 )) + getDistance(P( 15 ),P( 6 )); + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + aVal = Min(aVal,Min(Min(L7,L8),L9)); + } + break; + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: + if (len >= 20) { // quadratic hexahedron + double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 12 )) + getDistance(P( 12 ),P( 1 )); + double L5 = getDistance(P( 5 ),P( 13 )) + getDistance(P( 13 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 14 )) + getDistance(P( 14 ),P( 7 )); + double L7 = getDistance(P( 7 ),P( 15 )) + getDistance(P( 15 ),P( 8 )); + double L8 = getDistance(P( 8 ),P( 16 )) + getDistance(P( 16 ),P( 5 )); + double L9 = getDistance(P( 1 ),P( 17 )) + getDistance(P( 17 ),P( 5 )); + double L10= getDistance(P( 2 ),P( 18 )) + getDistance(P( 18 ),P( 6 )); + double L11= getDistance(P( 3 ),P( 19 )) + getDistance(P( 19 ),P( 7 )); + double L12= getDistance(P( 4 ),P( 20 )) + getDistance(P( 20 ),P( 8 )); + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10))); + aVal = Min(aVal,Min(L11,L12)); + } + break; + case SMDSEntity_Polygon: + if ( len > 1 ) { + aVal = getDistance( P(1), P( P.size() )); + for ( size_t i = 1; i < P.size(); ++i ) + aVal = Min( aVal, getDistance( P( i ), P( i+1 ))); + } + break; + case SMDSEntity_Quad_Polygon: + if ( len > 2 ) { + aVal = getDistance( P(1), P( P.size() )) + getDistance( P(P.size()), P( P.size()-1 )); + for ( size_t i = 1; i < P.size()-1; i += 2 ) + aVal = Min( aVal, getDistance( P( i ), P( i+1 )) + getDistance( P( i+1 ), P( i+2 ))); + } + break; + case SMDSEntity_Hexagonal_Prism: + if (len == 12) { // hexagonal prism + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 5 )); + double L5 = getDistance(P( 5 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 1 )); + + double L7 = getDistance(P( 7 ), P( 8 )); + double L8 = getDistance(P( 8 ), P( 9 )); + double L9 = getDistance(P( 9 ), P( 10 )); + double L10= getDistance(P( 10 ),P( 11 )); + double L11= getDistance(P( 11 ),P( 12 )); + double L12= getDistance(P( 12 ),P( 7 )); + + double L13 = getDistance(P( 1 ),P( 7 )); + double L14 = getDistance(P( 2 ),P( 8 )); + double L15 = getDistance(P( 3 ),P( 9 )); + double L16 = getDistance(P( 4 ),P( 10 )); + double L17 = getDistance(P( 5 ),P( 11 )); + double L18 = getDistance(P( 6 ),P( 12 )); + aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); + aVal = Min(aVal, Min(Min(Min(L7,L8),Min(L9,L10)),Min(L11,L12))); + aVal = Min(aVal, Min(Min(Min(L13,L14),Min(L15,L16)),Min(L17,L18))); + } + break; + case SMDSEntity_Polyhedra: + { + } + break; + default: + return 0; + } + if (aVal < 0 ) { + return 0.; } - return 0.; + + if ( myPrecision >= 0 ) + { + double prec = pow( 10., (double)( myPrecision ) ); + aVal = floor( aVal * prec + 0.5 ) / prec; + } + + return aVal; } double Length2D::GetBadRate( double Value, int /*nbNodes*/ ) const @@ -1906,6 +1908,97 @@ void Length2D::GetValues(TValues& theValues) } } +//================================================================================ +/* + Class : Deflection2D + Description : Functor for calculating number of faces conneted to the edge +*/ +//================================================================================ + +double Deflection2D::GetValue( const TSequenceOfXYZ& P ) +{ + if ( myMesh && P.getElement() ) + { + // get underlying surface + if ( myShapeIndex != P.getElement()->getshapeId() ) + { + mySurface.Nullify(); + myShapeIndex = P.getElement()->getshapeId(); + const TopoDS_Shape& S = + static_cast< const SMESHDS_Mesh* >( myMesh )->IndexToShape( myShapeIndex ); + if ( !S.IsNull() && S.ShapeType() == TopAbs_FACE ) + { + mySurface = new ShapeAnalysis_Surface( BRep_Tool::Surface( TopoDS::Face( S ))); + + GeomLib_IsPlanarSurface isPlaneCheck( mySurface->Surface() ); + if ( isPlaneCheck.IsPlanar() ) + myPlane.reset( new gp_Pln( isPlaneCheck.Plan() )); + else + myPlane.reset(); + } + } + // project gravity center to the surface + if ( !mySurface.IsNull() ) + { + gp_XYZ gc(0,0,0); + gp_XY uv(0,0); + int nbUV = 0; + for ( size_t i = 0; i < P.size(); ++i ) + { + gc += P(i+1); + + if ( const SMDS_FacePosition* fPos = dynamic_cast + ( P.getElement()->GetNode( i )->GetPosition() )) + { + uv.ChangeCoord(1) += fPos->GetUParameter(); + uv.ChangeCoord(2) += fPos->GetVParameter(); + ++nbUV; + } + } + gc /= P.size(); + if ( nbUV ) uv /= nbUV; + + double maxLen = MaxElementLength2D().GetValue( P ); + double tol = 1e-3 * maxLen; + double dist; + if ( myPlane ) + { + dist = myPlane->Distance( gc ); + if ( dist < tol ) + dist = 0; + } + else + { + if ( uv.X() != 0 && uv.Y() != 0 ) // faster way + mySurface->NextValueOfUV( uv, gc, tol, 0.5 * maxLen ); + else + mySurface->ValueOfUV( gc, tol ); + dist = mySurface->Gap(); + } + return Round( dist ); + } + } + return 0; +} + +void Deflection2D::SetMesh( const SMDS_Mesh* theMesh ) +{ + NumericalFunctor::SetMesh( dynamic_cast( theMesh )); + myShapeIndex = -100; + myPlane.reset(); +} + +SMDSAbs_ElementType Deflection2D::GetType() const +{ + return SMDSAbs_Face; +} + +double Deflection2D::GetBadRate( double Value, int /*nbNodes*/ ) const +{ + // meaningless as it is not quality control functor + return Value; +} + //================================================================================ /* Class : MultiConnection @@ -2116,6 +2209,42 @@ SMDSAbs_ElementType BallDiameter::GetType() const return SMDSAbs_Ball; } +//================================================================================ +/* + Class : NodeConnectivityNumber + Description : Functor returning number of elements connected to a node +*/ +//================================================================================ + +double NodeConnectivityNumber::GetValue( long theId ) +{ + double nb = 0; + + if ( const SMDS_MeshNode* node = myMesh->FindNode( theId )) + { + SMDSAbs_ElementType type; + if ( myMesh->NbVolumes() > 0 ) + type = SMDSAbs_Volume; + else if ( myMesh->NbFaces() > 0 ) + type = SMDSAbs_Face; + else if ( myMesh->NbEdges() > 0 ) + type = SMDSAbs_Edge; + else + return 0; + nb = node->NbInverseElements( type ); + } + return nb; +} + +double NodeConnectivityNumber::GetBadRate( double Value, int /*nbNodes*/ ) const +{ + return Value; +} + +SMDSAbs_ElementType NodeConnectivityNumber::GetType() const +{ + return SMDSAbs_Node; +} /* PREDICATES @@ -2614,7 +2743,7 @@ bool FreeFaces::IsSatisfy( long theId ) for ( ; volItr != volEnd; ++volItr ) if ( (*volItr).second >= nbNode ) nbVol++; - // face is not free if number of volumes constructed on thier nodes more than one + // face is not free if number of volumes constructed on their nodes more than one return (nbVol < 2); } @@ -2662,7 +2791,7 @@ SMDSAbs_ElementType LinearOrQuadratic::GetType() const //================================================================================ /* Class : GroupColor - Description : Functor for check color of group to whic mesh element belongs to + Description : Functor for check color of group to which mesh element belongs to */ //================================================================================ @@ -3220,7 +3349,7 @@ bool RangeOfIds::SetRangeStr( const TCollection_AsciiString& theStr ) { char c = aStr.Value( i ); if ( !isdigit( c ) && c != ',' && c != '-' ) - aStr.SetValue( i, ' '); + aStr.SetValue( i, ','); } aStr.RemoveAll( ' ' ); @@ -4097,7 +4226,8 @@ namespace { struct ElementsOnShape::Classifier { - //Classifier(const TopoDS_Shape& s, double tol) { Init(s,tol); } + Classifier() { mySolidClfr = 0; myFlags = 0; } + ~Classifier(); void Init(const TopoDS_Shape& s, double tol, const Bnd_B3d* box = 0 ); bool IsOut(const gp_Pnt& p) { return SetChecked( true ), (this->*myIsOutFun)( p ); } TopAbs_ShapeEnum ShapeType() const { return myShape.ShapeType(); } @@ -4108,6 +4238,7 @@ struct ElementsOnShape::Classifier void SetChecked( bool is ) { is ? SetFlag( theIsCheckedFlag ) : UnsetFlag( theIsCheckedFlag ); } void SetFlag ( int flag ) { myFlags |= flag; } void UnsetFlag( int flag ) { myFlags &= ~flag; } + private: bool isOutOfSolid (const gp_Pnt& p); bool isOutOfBox (const gp_Pnt& p); @@ -4116,15 +4247,15 @@ private: bool isOutOfVertex(const gp_Pnt& p); bool isBox (const TopoDS_Shape& s); - bool (Classifier::* myIsOutFun)(const gp_Pnt& p); - BRepClass3d_SolidClassifier mySolidClfr; - Bnd_B3d myBox; - GeomAPI_ProjectPointOnSurf myProjFace; - GeomAPI_ProjectPointOnCurve myProjEdge; - gp_Pnt myVertexXYZ; - TopoDS_Shape myShape; - double myTol; - int myFlags; + bool (Classifier::* myIsOutFun)(const gp_Pnt& p); + BRepClass3d_SolidClassifier* mySolidClfr; // ptr because of a run-time forbidden copy-constructor + Bnd_B3d myBox; + GeomAPI_ProjectPointOnSurf myProjFace; + GeomAPI_ProjectPointOnCurve myProjEdge; + gp_Pnt myVertexXYZ; + TopoDS_Shape myShape; + double myTol; + int myFlags; }; struct ElementsOnShape::OctreeClassifier : public SMESH_Octree @@ -4249,6 +4380,7 @@ void ElementsOnShape::SetShape (const TopoDS_Shape& theShape, if ( shapeChanges ) { + // find most complex shapes TopTools_IndexedMapOfShape shapesMap; TopAbs_ShapeEnum shapeTypes[4] = { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX }; TopExp_Explorer sub; @@ -4291,10 +4423,18 @@ void ElementsOnShape::clearClassifiers() bool ElementsOnShape::IsSatisfy( long elemId ) { - const SMDS_Mesh* mesh = myMeshModifTracer.GetMesh(); - const SMDS_MeshElement* elem = - ( myType == SMDSAbs_Node ? mesh->FindNode( elemId ) : mesh->FindElement( elemId )); - if ( !elem || myClassifiers.empty() ) + if ( myClassifiers.empty() ) + return false; + + const SMDS_Mesh* mesh = myMeshModifTracer.GetMesh(); + if ( myType == SMDSAbs_Node ) + return IsSatisfy( mesh->FindNode( elemId )); + return IsSatisfy( mesh->FindElement( elemId )); +} + +bool ElementsOnShape::IsSatisfy (const SMDS_MeshElement* elem) +{ + if ( !elem ) return false; bool isSatisfy = myAllNodesFlag, isNodeOut; @@ -4358,12 +4498,67 @@ bool ElementsOnShape::IsSatisfy( long elemId ) return isSatisfy; } +bool ElementsOnShape::IsSatisfy (const SMDS_MeshNode* node, + TopoDS_Shape* okShape) +{ + if ( !node ) + return false; + + if ( !myOctree && myClassifiers.size() > 5 ) + { + myWorkClassifiers.resize( myClassifiers.size() ); + for ( size_t i = 0; i < myClassifiers.size(); ++i ) + myWorkClassifiers[ i ] = & myClassifiers[ i ]; + myOctree = new OctreeClassifier( myWorkClassifiers ); + } + + bool isNodeOut = true; + + if ( okShape || !getNodeIsOut( node, isNodeOut )) + { + SMESH_NodeXYZ aPnt = node; + if ( myOctree ) + { + myWorkClassifiers.clear(); + myOctree->GetClassifiersAtPoint( aPnt, myWorkClassifiers ); + + for ( size_t i = 0; i < myWorkClassifiers.size(); ++i ) + myWorkClassifiers[i]->SetChecked( false ); + + for ( size_t i = 0; i < myWorkClassifiers.size(); ++i ) + if ( !myWorkClassifiers[i]->IsChecked() && + !myWorkClassifiers[i]->IsOut( aPnt )) + { + isNodeOut = false; + if ( okShape ) + *okShape = myWorkClassifiers[i]->Shape(); + break; + } + } + else + { + for ( size_t i = 0; i < myClassifiers.size(); ++i ) + if ( !myClassifiers[i].IsOut( aPnt )) + { + isNodeOut = false; + if ( okShape ) + *okShape = myWorkClassifiers[i]->Shape(); + break; + } + } + setNodeIsOut( node, isNodeOut ); + } + + return !isNodeOut; +} + void ElementsOnShape::Classifier::Init( const TopoDS_Shape& theShape, double theTol, const Bnd_B3d* theBox ) { myShape = theShape; myTol = theTol; + myFlags = 0; bool isShapeBox = false; switch ( myShape.ShapeType() ) @@ -4376,7 +4571,7 @@ void ElementsOnShape::Classifier::Init( const TopoDS_Shape& theShape, } else { - mySolidClfr.Load(theShape); + mySolidClfr = new BRepClass3d_SolidClassifier(theShape); myIsOutFun = & ElementsOnShape::Classifier::isOutOfSolid; } break; @@ -4432,10 +4627,15 @@ void ElementsOnShape::Classifier::Init( const TopoDS_Shape& theShape, } } +ElementsOnShape::Classifier::~Classifier() +{ + delete mySolidClfr; mySolidClfr = 0; +} + bool ElementsOnShape::Classifier::isOutOfSolid (const gp_Pnt& p) { - mySolidClfr.Perform( p, myTol ); - return ( mySolidClfr.State() != TopAbs_IN && mySolidClfr.State() != TopAbs_ON ); + mySolidClfr->Perform( p, myTol ); + return ( mySolidClfr->State() != TopAbs_IN && mySolidClfr->State() != TopAbs_ON ); } bool ElementsOnShape::Classifier::isOutOfBox (const gp_Pnt& p) @@ -4449,7 +4649,7 @@ bool ElementsOnShape::Classifier::isOutOfFace (const gp_Pnt& p) if ( myProjFace.IsDone() && myProjFace.LowerDistance() <= myTol ) { // check relatively to the face - Quantity_Parameter u, v; + Standard_Real u, v; myProjFace.LowerDistanceParameters(u, v); gp_Pnt2d aProjPnt (u, v); BRepClass_FaceClassifier aClsf ( TopoDS::Face( myShape ), aProjPnt, myTol ); @@ -4524,7 +4724,7 @@ OctreeClassifier::OctreeClassifier( const OctreeClassifier* } else if ( otherTree->myChildren ) { - myChildren = new SMESH_Tree < Bnd_B3d, 8 >*[ 8 ]; + myChildren = new SMESH_Tree< Bnd_B3d, 8 > * [ 8 ]; for ( int i = 0; i < nbChildren(); i++ ) myChildren[i] = new OctreeClassifier( static_cast( otherTree->myChildren[i]),